I am using MVVM. I want to implement Firebase Auth in app. But to implement it I need an activity context in my repo class. How can I get it from ViewModel or is there any simple method available?
Here is the firebase code I need to implement:
PhoneAuthProvider.getInstance().verifyPhoneNumber("+91"+phone, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
(Activity) context, // Activity (for callback binding)
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential)
{
signInWithPhoneAuthCredential((Activity)context,phoneAuthCredential);
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
setLoginFailed(e);
}
@Override
public void onCodeSent(@NonNull String s, @NonNull
PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
loginResponse.setOnProgress(false);
loginResponse.setStatus(true);
loginResponse.setCodeVerified(false);
loginResponseLiveData.setValue(loginResponse);
verificationId =s;
}
});
In general, ViewModel objects are not supposed to reference anything that has to do with the Android platform APIs, especially Activity objects. You would not want a ViewModel to retain (and leak) an Activity across orientation changes. Retaining Activity objects in a ViewModel is a huge anti-pattern that should be avoided.
Instead, you should use a different version of that Firebase API. Choose one of the alternatives that do not take an Activity, according to the API documentation. Once the API is complete, you can bubble a callback up to the hosting activity to start any other activities.
First of all, according to official view model guidelines:
Caution: A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity content
So in accordance with your MVVM architecture, don't pass your activity context to a ViewModel.
I guess in that method you want to implement you do not specifically need an activity context. You could also use the context of your application.
Follow these 3 steps of this answer to get access your Application context statically:
context on create
public class MyApplication extends Application {
private static Context context;
public void onCreate() {
super.onCreate();
MyApplication.context = getApplicationContext();
}
public static Context getAppContext() {
return MyApplication.context;
}
}
<application android:name="com.xyz.MyApplication">
</application>
MyApplication.getAppContext()
There is also the possibility to access the application context via AndroidViewModel class. But I guess you usually do not want to initialize your repository from your ViewModel.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With