I have an activity where I get the uid
of a user from Firebase authentication:
public class MainActivity extends DaggerAppCompatActivity {
@Inject UserViewModel userViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
userViewModel.setUid(uid);
}
}
I'm using this uid
in my view model class:
public class UserViewModel extends ViewModel {
private CollectionReference usersRef;
@Inject
UsersViewModel(CollectionReference usersRef) {
this.usersRef = usersRef;
}
void setUid(String uid) {
DocumentReference uidRef = usersRef.document(uid);
//Use uidRef
}
}
And this my app module class:
class AppModule {
@Singleton
@Provides
static FirebaseFirestore provideFirebaseFirestoreInstance() {
return FirebaseFirestore.getInstance();
}
@Singleton
@Provides
static CollectionReference provideUsersCollectionRef(FirebaseFirestore db) {
return db.collection("users");
}
@Singleton
@Provides
static DocumentReference provideUidDocumentRef(CollectionReference usersRef) {
return usersRef.document(uid); //How to add the uid here
}
}
The question is, how can I add the uid
in the app module class, so I can inject the DocumentReference directly in my view model class like this:
public class UserViewModel extends ViewModel {
private DocumentReference uidRef;
@Inject
UserViewModel(DocumentReference uidRef) {
this.uidRef= uidRef;
//Use uidRef
}
}
You have the correct mindset in trying to inject dependencies but unfortunately, not all dependencies can be provided via constructor injection
, some of them need some information that is only known at runtime.
Look at your code, UserViewModel
is injected in MainActivity
, some of its dependencies were provided via constructor injection but you have to provide its uid
dependency via a setter injection
in the line userViewModel.setUid(uid);
once the uid is retrieved at runtime.
Your code seem fine in retrieving the DocumentReference
from the list once the uid is known. Maybe change your code in MainActivity to retrieve the DocumentReference and provide it via setter to UserViewModel?
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
userViewModel.setDocumentReference(db.collection("users").document(uid));
If you really want to inject the DocumentReference directly in your view model class like you described, you can add the uid as a constructor parameter to your AppModule.
But assuming that your AppModule is used by your AppComponent which is created in your Application class, you won't have the uid in the Application class to create the AppModule.
So you will have to create another component for your UserViewModel class, something like UserComponent. And create a UserModule which receives the uid as parameter in the constructor.
Then in your MainActivity, once you retrieve the uid, you create the UserComponent:
UserComponent userComponent = DaggerUserComponent.builder().userModule(new UserModule(uid)).build();
userViewModel.setUserComponent(userComponent);
and this is how your UserViewModel will look like:
public class UserViewModel extends ViewModel {
@Inject
private DocumentReference uidRef;
public void setUserComponent(UserComponent userComponent) {
userComponent.inject(this);
}
}