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?
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:
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.
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.
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. So, one option is to have the user set their password via a _firebaseAuth.sendPasswordResetEmail(email: email);
Also: I don't recommend turning off One account per email address
as some others suggests. See the reason for that at the end.
One account per email address
In my app, the following happens.
c_example_account@gmail.com
with provider=Email/Password as indicated by the envelope/mail icon in the firebaseAuth dashboard. c_example_account@gmail.com
User UID
is the same. So anything anything linked to that User UID
is still okay.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 .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 error Email is not found...
Now, it gets a little weirder...
Future<void> resetPassword(String email) async {
await _firebaseAuth.sendPasswordResetEmail(email: email);
}
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 .
User UID
, multiple login 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. ~~ 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
.
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.