'Can Dagger Hilt realise whether a variable in a Module class has changed and update its value?
I am writing an Android app that makes use of Firebase Auth and DI.
In this app, I regularly need to use the user's UID to perform some database operations, and in search of a way to stop passing the UID through MVVM layers, I've decided to give dependency injection a try.
My AppModule looks like this:
AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideServer(@ApplicationContext c: Context) = Server(c, Volley.newRequestQueue(c), provideUid())
@Singleton
@Provides
fun provideFirebase() = FirebaseSource(FirebaseAuth.getInstance())
@Singleton
@Provides
fun provideFirebaseAuth() = Firebase.auth
@Singleton
@Provides
fun provideFirebaseUser(): Boolean {
return provideFirebaseAuth().currentUser != null
}
@Singleton
@Provides
// FIXME
fun provideUid(): String {
return provideFirebaseAuth().currentUser?.uid ?: ""
}
}
Function provideUid() returns the Firebase current user's UID, and injects is as a dependency in a separate Server class:
Server.kt (part of)
class Server @Inject constructor(
private val c: Context,
private val volleyRequestQueue: RequestQueue,
private val uid: String
): IServer {
When the app starts for the first time, Dagger Hilt uses this constructor and provides a null UID because there is no logged-in user at the moment. This behavior persists for the rest of the app's lifecycle, and the Server class never has a non-null UID because it was already constructed with an empty UID as a property.
Restarting the app will construct the Server class with a non-empty UID because Firebase Auth keeps some registry of the user's auth state.
My question, then, is whether Dagger Hilt can realize the UID has changed and update its value or not.
Things I've tried:
- Deleting the
@Singletonannotation fromprovideUid() - Changing the
Server'suidparameter fromvaltovar.
Solution 1:[1]
You can try:
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideServer(@ApplicationContext c: Context, queue: RequestQueue, uid: String) = Server(c, queue, uid)
@Provides
@Singleton
fun provideResponseQueue(@ApplicationContext c: Context) = Volley.newRequestQueue(c)
@Singleton
@Provides
fun provideFirebase() = FirebaseSource(FirebaseAuth.getInstance())
@Singleton
@Provides
fun provideFirebaseAuth() = Firebase.auth
@Singleton
@Provides
fun provideFirebaseUser(): Boolean {
return provideFirebaseAuth().currentUser != null
}
@Provides
// FIXME
fun provideUid(): String {
return provideFirebaseAuth().currentUser?.uid ?: ""
}
}
If an instance of the Server object is created once in the application, this solution should not work.
Solution 2:[2]
Can Dagger Hilt realize whether a variable in a Module class has changed and then update its value?
The simplest answer is no, it cannot.
To let Dagger Hilt provide an instance for the FirebaseAuth, you can only use:
@Provides
fun provideFirebaseAuth() = FirebaseAuth.getInstance()
If you want to use the above instance in another method, as @Nitrodon already pointed out, you should pass that instance as an argument to the next method and not call it directly. So in code should look like this:
@Provides
fun provideFirebaseUser(auth: FirebaseAuth) = auth.currentUser
However, that's not useful since the currentUser object can be null according to the auth state of the user. Besides that, when an object is created, you can use it but it won't be recreated. So it doesn't make any sense to add this in your AppModule class. What you should do instead is inject an instance of FirebaseAuth in your application code, and check the currentUser against nullity. If it's not null, then you can safely use the UID.
If you want to know the auth state, then you should attach an AuthStateListener as explained in my answer from the following post:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | plplmax |
| Solution 2 | Alex Mamo |
