Firebase logging in with new provider (Google) removes previous provider (password)
I figured it out. Firebase behaves as it should and this was not a technical/coding problem. It's more of a documentation issue.
When a user signs up with email and password, logs out and signs in with a different method (that wasn't used before), two things can happen:
- If the email is confirmed, the email/password credentials are remembered when you login with a new provider (the desired outcome in my question).
or
- If the email is unconfirmed, the user is updated such that the email/password credentials are removed and the new login method will be kept. User details like
displayName
are not updated automatically.
Firebase authentication provider silently changes from password to google.com
Firebase Authentication has a concept of a preferred provider for certain email addresses. The most common one is that google.com is the preferred provider for @gmail.com
addresses, but I think they also exist for Facebook and Microsoft accounts.
If an existing account later signs up again from a preferred provider, that provider overwrites the existing user account. There is no way to change this behavior (that I know of).
Also see:
- Github issue Facebook provider overwritten by Google provider
- Mailing list Firebase Social Authentication Issue with fb and gmail flow
- Authentication using Facebook at first and then Google causes an error in Firebase for Android
Google Sign-in removes existing user data
What I want is The user logs in with his registered email and password and then logs out. When he goes in for login via Google, there needs to be an error toast preventing him from signing in via Google if the same email address has been registered already. Basically, if his email address has been registered, then he can log in only via email and password authentication and not via Google.
The flow for solving this problem is to ask the user for the email address from the beginning. Once you have the email address you can check if the user has already an account or not. Assuming that you have distinct buttons for each authentication provider you can display or hide them according to what the user has selected for authentication first time. For instance, if the user has selected the authentication with email and password, check that using:
auth.fetchSignInMethodsForEmail(email).addOnCompleteListener(signInMethodsTask -> {
if (signInMethodsTask.isSuccessful()) {
List<String> signInMethods = signInMethodsTask.getResult().getSignInMethods();
for (String signInMethod : signInMethods) {
switch (signInMethod) {
case GoogleAuthProvider.PROVIDER_ID:
googleSignInButton.setVisibility(VISIBLE);
facebookSignInButton.setVisibility(GONE);
passwordSignInButton.setVisibility(GONE);
break;
case FacebookAuthProvider.PROVIDER_ID:
googleSignInButton.setVisibility(GONE);
facebookSignInButton.setVisibility(VISIBLE);
passwordSignInButton.setVisibility(GONE);
break;
case EmailAuthProvider.PROVIDER_ID:
googleSignInButton.setVisibility(GONE);
facebookSignInButton.setVisibility(GONE);
passwordSignInButton.setVisibility(VISIBLE);
break;
default:
googleSignInButton.setVisibility(VISIBLE);
facebookSignInButton.setVisibility(VISIBLE);
passwordSignInButton.setVisibility(VISIBLE);
break;
}
}
}
});
In the case of EmailAuthProvider.PROVIDER_ID
, hide the other buttons and display only the button that provides the sign-in with email and password. If the user is new, display all buttons so the user can choose one or the other authentication options.
P.S. There is no need to let the user choose to sign-in with another provider if you only want to let the user sign-in with a particular one.
Android FirebaseUI: Signing in with another Google account is troublesome
According to the documentation:
Sign out
With the integrations provided by AuthUI, signing out a user is a
multi-stage process:
- The user must be signed out of the FirebaseAuth instance.
- Smart Lock for Passwords must be instructed to disable automatic sign-in, in order to prevent an automatic sign-in loop that prevents
the user from switching accounts.- If the current user signed in using either Google or Facebook, the user must also be signed out using the associated API for that
authentication method. This typically ensures that the user will not
be automatically signed-in using the current account when using that
authentication method again from the authentication method picker,
which would also prevent the user from switching between accounts on
the same provider.
In order to make this process easier, AuthUI provides a simple signOut
method to encapsulate this behavior. The method returns a Task which
is marked completed once all necessary sign-out operations are
completed:AuthUI.getInstance()
.signOut(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
public void onComplete(@NonNull Task<Void> task) {
// user is now signed out
startActivity(new Intent(MyActivity.this, SignInActivity.class));
finish();
}
});
Related Topics
Add "View More" at the End of Textview After 3 Lines
Handling a Menu Item Click Event - Android
Android Remove Space Between Tabs in Tabwidget
Android: Change Shape Color in Runtime
Android: Share Plain Text Using Intent (To All Messaging Apps)
Android Studio Not Deploying Changes to App
Appcompatv7 - V21 Navigation Drawer Not Showing Hamburger Icon
How to Sync SQLite Database on Android Phone with MySQL Database on Server
How to Pass a View's Onclick Event to Its Parent on Android
How to Solve the Install_Failed_Dexopt Error
Android: Implementing Progressbar and "Loading..." for Endless List Like Android Market
How to Make a Phone Call Programmatically
Sqlite Android Database Cursor Window Allocation of 2048 Kb Failed
How to Add Items to a Spinner in Android
How to Set Font Custom Font to Spinner Text Programmatically