According to this post and some other blog posts, It is bad to have Activity Context in a presenter in an MVP android app. What if one of the method in the presenter requires an Activity context, how can I remove the Activity context in the presenter and still have the presenter does the job it needs to get done?
In this Activity, it calls the method firebaseAuthWithGoogle in the presenter. The presenter is initialized by passing the activity, view and FirebaseAuth to the constructor.
public class GoogleSignInActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener, View.OnClickListener, GoogleSignInView {
private static final String TAG = "SignInActivity";
private static final int RC_SIGN_IN = 9001;
private SignInButton mSignInButton;
private GoogleApiClient mGoogleApiClient;
// Firebase instance variables
private FirebaseAuth mFirebaseAuth;
private GoogleSignInPresenter googleSignInPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_sign_in);
mSignInButton = (SignInButton) findViewById(R.id.btn_sign_in);
mSignInButton.setOnClickListener(this);
// Configure Google Sign In
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
// Initialize FirebaseAuth
mFirebaseAuth = FirebaseAuth.getInstance();
googleSignInPresenter = new GoogleSignInPresenter(this, this, mFirebaseAuth);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
googleSignInPresenter.onSignInClick();
break;
default:
return;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
GoogleSignInAccount account = result.getSignInAccount();
googleSignInPresenter.firebaseAuthWithGoogle(account);
} else {
Log.e(TAG, "Google Sign-In failed.");
}
}
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed:" + connectionResult);
Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}
@Override
public void startSignInIntent() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
@Override
public void startMainActivity() {
startActivity(new Intent(GoogleSignInActivity.this, MainActivity.class));
finish();
}
}
The method firebaseAuthWithGoogle in this presenter requires the Activity context in the addOnCompleteListener.
public class GoogleSignInPresenter {
public static final String TAG = "GoogleSignInPresenter";
private GoogleSignInView googleSignInView;
private FirebaseAuth firebaseAuth;
private GoogleSignInActivity googleSignInActivity;
public GoogleSignInPresenter(GoogleSignInActivity googleSignInActivity, GoogleSignInView googleSignInView, FirebaseAuth firebaseAuth) {
this.googleSignInActivity = googleSignInActivity;
this.googleSignInView = googleSignInView;
this.firebaseAuth = firebaseAuth;
}
public void onSignInClick() {
googleSignInView.startSignInIntent();
}
public void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
Log.d(TAG, "firebaseAuthWithGooogle:" + acct.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(googleSignInActivity, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
if (!task.isSuccessful()) {
Log.w(TAG, "signInWithCredential", task.getException());
} else {
googleSignInView.startMainActivity();
}
}
});
}
}