I have been using Firebase Authentication in my app, and have noticed an issue with a particular use case.
I have enabled account linking sign up flow for my app, and thus I can attach multiple providers associated with a single email address.
Scenario 1: (Works fine)
The user has signed up with Google initially and sometime later, signs in in with Facebook or registers with email and password.
The account linking works fine and Facebook and/or Email is added in the provider list.
So, I can have 2 or 3 providers for the email, Google (initially), Facebook and Password (after that).
Scenario 2: (The bug)
The user has signed up with Facebook and/or Email initially and later signs in with Google, now the account linking doesn't work. Google replaces the previous providers present.
Account linking fails, and I just have Google as the sole provider associated with the email address and the others are gone.
In the second scenario, while signing in with Google, it should fail and throw FirebaseAuthCollisionException but it doesn't and succeeds. This is the main issue.
I can't paste the whole code here, but just a snippet for sure.
firebaseAuth
.signInWithCredential(credential)
.addOnFailureListener(exception -> {
if (exception instanceof FirebaseAuthUserCollisionException) {
mCredentialToLinkWith = credential;
if (mProviderList.size() == 1) {
if (mProviderList.contains(EmailAuthProvider.PROVIDER_ID)) {
mRegisterProviderPresenter.linkWithEmailProvider(credential, email);
} else {
linkProviderAccounts(email, AuthenticationHelper.getProviderToLinkAccounts(mWeakActivity, mProviderList));
}
} else {
linkProviderAccounts(email, AuthenticationHelper.getProviderToLinkAccounts(mWeakActivity, mProviderList));
}
} else {
Timber.d("Failed in signInWithCredential and unexpected exception %s", exception.getLocalizedMessage());
mRegisterProviderPresenter.onRegistrationFailed(new ErrorBundle(ErrorBundle.FIREBASE_ERROR, exception.getLocalizedMessage()));
}
})
.addOnSuccessListener(authResult -> {
Timber.d("Success: signInCred");
FirebaseUser firebaseUser = authResult.getUser();
/**
* Store the user details only for first time registration
* and not while acc linking
*/
storeUserCredentials(firebaseUser);
AuthenticationHelper.logUserDetails(firebaseUser);
mRegisterProviderPresenter.onRegistrationSuccess(mAlreadyRegistered);
});
Hope someone can come up with some help.