At the first time, while signup with Gmail and password, firebase saved the credentials correctly. But the next time, I Login with Firebase Google authentication with the same Gmail which i gave while signup, the credentials are overriding in firebase account. After overriding the credentials, we are not able to login using that signup credentials. Can anyone explain how to achieve this?
-
Go to Sign-In Method -> Advance option you will find this option -> One account per email address. Click on CHANGE -> Select first option (Prevent creation of multiple account with the same email address) – Hardik Thakkar Mar 03 '21 at 13:09
3 Answers
What happened
In the first screenshot you signed in with the email+password provider of Firebase. While this is a valid sign-in method, it means that anyone could've entered that email address, even if they don't actually have access to the Google account for that gmail address.
There is no security risk here, but the level of trust we can put in the value of email address is low. For this reason the emailVerified property of the account is marked as false and you'll typically want to require that the user verify their email address before allowing them to continue.
In the second screenshot, the user signed in with the same email address, but now with the google.com provider of Firebase. This means that Google now verified already that the user has access to the underlying gmail address of the account. Since the google.com provider is the trusted provider for @gmail.com accounts, the system replaces the previous account.
Also see:
- Authentication using Facebook at first and then Google causes an error in Firebase for Android
- Firebase Overwrites Signin with Google Account
- Trying to understand Firebase Authentication one account per email address and trusted providers
What you can do
You'll typically want to prevent multiple users from signing up with the same email address. For this, you'll want to configure Firebase to only allow a single account per email address in the console, and then use account linking so that the two (email+password and google.com) accounts in your scenario are merged.
- 565,676
- 79
- 828
- 807
Did you verify the email or phone number from the first login attempt? If not, this is by design:
After sign-in completion, any previous unverified mechanism of sign-in will be removed from the user and any existing sessions will be invalidated. For example, if someone previously created an unverified account with the same email and password, the user’s password will be removed to prevent the impersonator who claimed ownership and created that unverified account from signing in again with the unverified email and password.
- 3,648
- 16
- 29
I just ran into this problem and here is a longer and more in depth description. (Things change often, this was true in Nov 2021.)
SHORT VERSION: As @Frank van Puffelen said, this is by design. The issue is that email+password is not a trusted provider usually, so a trusted provider like Google Authentication overwrites that method. It does this silently (I think, didn't check every field in GoogleSignInAuthentication object.)
It does auto-link after a password reset OR the email is verified via a link. See https://firebase.flutter.dev/docs/auth/usage/#verifying-a-users-email on code to do that.
Also: I don't recommend turning off One account per email address as some others suggests . See the reason for that at the end.
"Weird" Behavior under default One account per email address
In my app, the following happens.
- SignUp via email+password for testUser1234@gmail.com.
- creates an account for
c_example_account@gmail.comwith provider=Email/Password as indicated by the envelope/mail icon in the firebaseAuth dashboard.
- LogOut and re-signin via Google Sign In for
c_example_account@gmail.com - The provider is changed. Old provider is Email/Password icon (envelope). New provider is Google icon. (like the bottom three accounts in the screenshot). Note also that the
User UIDis the same. So anything anything linked to thatUser UIDis still okay. - Since the Email/Password login method (AKA) provider was removed for
c_example_account@gmail.com, the user can't login with that method anymore. IMPORTANTLY: This is done silently without the user getting any notification that the Email/Password login was removed. - Trying to sign on using Email/Password will result in an error
Incorrect Password. Note: one might expect it to give an error like "Only Google Sign-In is available", but it doesn't. Contrast this to when the email doesn't exist (like trying garbage@123457.com), which has an errorEmail is not found...
Now, it gets a little weirder...
- Suppose the user uses "Reset Password" like being called like this
Future<void> resetPassword(String email) async {
await _firebaseAuth.sendPasswordResetEmail(email: email);
}
- Then, the firebaseAuth console has TWO methods for the same USER UID. See the second and third line in the screenshot.

- Now, both methods are allowed. The difference is that the first time was a
createUserWithEmailAndPassword()like
await _firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: password,
);
...but this time it was created via a "Reset" event
Future<void> resetPassword(String email) async {
await _firebaseAuth.sendPasswordResetEmail(email: email);
}
... that gave a link via email sent by firebaseAuth service. In this case, the email was verified.
- Recap: Now both methods work. The two methods being (1) Google authentication and (2) Email/Password. In Google parlance, the accounts have been linked: https://firebase.google.com/docs/auth/android/account-linking. Linking means One
User UID, multiple login methods
Why the funky behavior when Email/Password is created in two different methods?
~~I couldn't find this documented in firebaseAuth, maybe because I didn't look hard enough or maybe because it's not a common issue. ~~
UPDATE: This behavior is documented in an issue comment from April 2020.
I think the reason is because the _firebaseAuth.createUserWithEmailAndPassword version has an unverified email. So, anyone can create an account for anyone else assuming that the email+password combination doesn't exist. For example, I could create an account with username president@whitehouse.gov without actually having access to that email. If the actual president logged in via Google Authentication, then I'd have bogus access to that user's info. Except that the clever google engineers decided that the verified Google Authentication then triggers the deletion of the unverified Email/Password provider/account instance.
In short, the logic might be: verified trumps/overrides unverified. See https://firebase.google.com/docs/auth/users#verified_email_addresses
Again, none of this is documented explicitly for Email/Password. But it is hinted at in the documentation, like if a Facebook Auth account gets over-written by a Google Auth.
Snapshot of the Verified Email details
Copied from: https://firebase.google.com/docs/auth/users#verified_email_addresses
Bolded added by me, for emphasis
In some situations, Firebase will automatically link accounts when a user signs in with different providers using the same email address. This can only happen when specific criteria are met, however. To understand why, consider the following situation: a user signs in using Google with a @gmail.com account and a malicious actor creates an account using the same @gmail.com address, but signing in via Facebook. If these two accounts were automatically linked, the malicious actor would gain access to the user's account.
The following cases describe when we automatically link accounts and when we throw an error requiring user or developer action:
- User signs in with an untrusted provider, then signs in with another untrusted provider with the same email (for example, Facebook followed by GitHub). This throws an error requiring account linking.
- User signs in with a trusted provider, then signs in with untrusted provider with the same email (for example, Google followed by Facebook). This throws an error requiring account linking.
- User signs in with an untrusted provider, then signs in with a trusted provider with the same email (for example, Facebook followed by Google). The trusted provider overwrites the untrusted provider. If the user attempts to sign in again with Facebook, it will cause an error requiring account linking.
- User signs in with a trusted provider, then signs in with a different trusted provider with the same email (for example, Apple followed by Google). Both providers will be linked without errors.
You can manually set an email as verified by using the Admin SDK, but we recommend only doing this if you know the user really does own the email.
Why not turn off One account per email address
By default, the setting One account per email address is active as @Deva wrote. But, unchecking this means that there are two different accounts (User UIDs) for the same email. One via Email/Password and one via Google Authentication. They will have separate User UIDs in Firebase Auth, so that may confuse you. Furthermore, if you manually link in your app two User UIDs, this creates a security hole: Someone can create an account without email verification to get access to an existing account. So don't do that.
Related StackOverflow questions and links
- 2,447
- 4
- 21
- 23
-
Forgive the dumb question, but isn't the way to get around this security gap to only 'link' the accounts in your backend once the user has verified their email? If a user hasn't verified their email address, they can't access the data associated with their account email. The 2nd Firebase UID is 'dangling' until that account is correctly set-up, which isn't a security threat? As for the db, multiple UIDs may not be so much of an issue because (i) most people are just using Firebase just for auth, (ii) email probably makes a more useful key for your separate db. Or am I missing something? – Imran Ahmed May 18 '22 at 14:46
-
@ImranAhmed Yes, as long as you mean verified via firebase_auth and not your backend. And, if you have 2 firebase uids (verified) linked to one of your backend uids, that's fine. The difficulty is that there are probably at least 3x3 =9 ways to set it up. And not all 9 ways are secure. – chongman May 19 '22 at 17:00
-
Thanks for confirming, super helpful! And yes, the plan is to validate via firebase_auth :) Will try and keep a lookout for edge-cases that pop-up for this, and will note down any here if I run into them. – Imran Ahmed May 22 '22 at 14:06

