I've recently started teaching myself kotlin and am building an App to get to grips with application fundamentals.. so appologies if the answer is out there somewhere but I couldn't find a relevant solution.
I have a LoginActivity.kt that sets up a LoginViewModel that contains a live mutable variable for the login result like so
class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel() {
private val _loginForm = MutableLiveData<LoginFormState>()
val loginFormState: LiveData<LoginFormState> = _loginForm
private val _loginResult = MutableLiveData<LoginResult>()
val loginResult: MutableLiveData<LoginResult> = _loginResult
fun login(email: String, password: String) {
runBlocking {
// do login
}
}
fun loginDataChanged(username: String, password: String) {
// validate login fields
}
private fun isUserNameValid(username: String): Boolean {
// validate username fields
}
// A placeholder password validation check
private fun isPasswordValid(password: String): Boolean {
// validate passwordfields
}
}
This all works fine so far with the ViewModel, by way of the Model and View, communicate with the server I've set up thereby authenticating the user login credentials.
On a successful login I run
private fun updateUiWithUser(loggedInUser: LoggedInUser) {
startActivity(
Intent(
this@LoginActivity,
MainActivity::class.java
).putExtra("loggedInUser", loggedInUser)
)
}
which sets up the main activity
class MainActivity : AppCompatActivity() {
lateinit var loggedInUser : LoggedInUser // ? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loggedInUser = intent.getParcelableExtra("loggedInUser")!!
Log.v("Main auth token", loggedInUser.token)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
}
this all works so far and on a success login the the Log displays that the loggedInUser variable is set
I would then like to access the logged in users authentication token from a view that will perform authenticated communication with the server EXCEPT I can't figure out a way to do so :/
My thought was that I would be able to do something like MainActivity().loggedInUser.token in the retrofit factory like so
fun getAuthorizedRetrofit(): Retrofit {
val authorizationToken = MainActivity().loggedInUser.token
Log.v("retro builder auth", authorizationToken)
val client: OkHttpClient = OkHttpClient.Builder().addInterceptor(object : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val newRequest: Request = chain.request().newBuilder()
.addHeader("Authorization", "Token ${authorizationToken}")
.build()
return chain.proceed(newRequest)
}
}).build()
return Retrofit.Builder()
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(API.BASE_URL)
.build()
}
but of course at this point it is trying to instantiate a new MainActivity so there is no initiated logged in user.
I feel like I am missing some fundamental way of accessing the login authentication data from my login repository but to my knowledge this is lost once it is not required in context any more?
Am I missing some key understanding of how classes are instantiated, handled and accessed or is there just an error with my approach? If the latter, how do I make the user authentication credentials available to any view that might want to communicate with the server?
The server is all set up in django with postgresql database and all the api call works from the app with hard coded authenication credentials but obviously this is not a working solution.
I've tried to be verbose for future googlers but if something needs to be clearer please comment :)