Firebase : Authentication providers different email address - firebase

If I register with Facebook (x#x.com) and later log in with Google (y#y.com), but I do not have the same email address on both providers, there are 2 users created. How can I handle this situation?

Linking is typically used in three cases:
Automatically requested by the backend for security reasons: when a user signs in to google for example with email x#x and then logs out and tries to sign in with a new facebook account x#x. In this case the backend will not complete the second sign in without verifying that the second user is the same as the first user (since both use the same email). So in this case, the user has to sign to the google account and then link the second facebook account to the initial one.
Manually triggered by the developer: One common case here is that the user signs in to google with email x#x and remains signed in. The developer wants access to the user's facebook friends. So the developer will ask the user to link their facebook account to the already logged in google user.
Upgrading an anonymous user: Developer could automatically sign in users initially as anonymous and then prompt them to upgrade to a registered user. In this case you can call link on the anonymous user.
So auth.currentUser.link can be made on all kinds of users as long as the account you are linking is new and not already linked.

You'll want to use the Account Linking APIs to authenticate multiple providers for the same account. Docs for Web, Android, and iOS are available.

Related

Firebase authentication Twitter and Google

I am using the Firebase authentication functionality. I am using Facebook, Google, Twitter and email and password as providers. The default functionality is to use a single email by authentication.
If I authenticate with an account with Facebook, Twitter or Google and then try to enter but using email and password to do it, it shows me a warning where it says that I already use another authentication method and it allows me to do it with the previous one.
If I authenticate with email and password and then try to authenticate with Google, Twitter or Facebook these authentication methods overlap, that is, take both and in the Firebase console I can see that they are both.
Now, if I authenticate with email and password, Facebook (I think) or Twitter and then try to authenticate with Google, it deletes the previous authentication methods. That is, if with the first authentication methods I had id1 after authenticating with Google, the entry with id1 is deleted and one is created with id2.
This generates a problem in my application because it is a way to lose the user's registry previously created with id1.
I'm not sure if this is the expected behavior but I do not think so. Obviously whenever I refer to doing a 'new authentication' with another method I make sure to use the same email.
It sounds like you are looking for account-linking. This is possible in Firebase-authentication. Users are identified by their Firebase Userid and you can link multiple authentication providers to a userid.
Try to check this documentation. I think this is what you are looking for: https://firebase.google.com/docs/auth/web/account-linking
I hope it helps.
The Google provider overwriting the existing providers is due to Google emails being verified as Google owns these email addresses.
To work around this, you will need to verify the email after the user signs up by sending an email verification. This guarantees that Google sign-in will not unlink the providers as the email is considered to be verified. So if a user signs up with Facebook (using a Google email), verify the email so next time the user signs in with the same Google email, the Facebook provider would remain on the user.

Firebase disable automatic login account creation

I am building a web and mobile app using firebase. When signing with Google, firebase auto creates a new account in the project (Auth) if one does not exist. Its fine with the mobile app.
But with the web, I just want existing users (who created accounts with mobile app) to signin and not create new accounts via web.
How do I setup firebase not to create new accounts if one does not exist?
There isn't a way to restrict social sign-in with Firebase Auth to "only sign in, not sign up".
If you have a means of detecting users that have signed in using the app at some point (e.g. by writing a value to your database in a specific location), you could check for that value when signing in via the web, and, if missing, display a screen encouraging users to install the mobile app.
I think this is what you are looking for:
Link Multiple Auth Providers to an Account Using
JavaScript
You can allow users to sign in to your app using multiple
authentication providers by linking auth provider credentials to an
existing user account. Users are identifiable by the same Firebase
user ID regardless of the authentication provider they used to sign
in. For example, a user who signed in with a password can link a
Google account and sign in with either method in the future. Or, an
anonymous user can link a Facebook account and then, later, sign in
with Facebook to continue using your app.

Firebase: Link facebook account with existing user

I have a current database with active users in Firebase that can login with user/pwd but now I'm implementing the facebook login and I realised the only way to link a facebook account with an existing user is only when the user is already logged with the user/pwd but not before the login.
I have two buttons in my app (login with fb and with email) but if I try to login with fb using the same email of an existing user, I will receive the following error auth/account-exists-with-different-credential and the documentation says that in order to fix this the user needs to login first then link.
Do you know if there is a way to link both accounts but without perform a login first, I mean, from the login view?
You need to sign in the user first before linking. This is important if you want to ensure it is the same user. Otherwise you can switch to multiple accounts per email in the Firebase console.
The way to solve this, when you get the error auth/account-exists-with-different-credential, the error will contain error.email and error.credential after you sign in with Facebook and the account already exists as a password account.
You then call firebase.auth().fetchProvidersForEmail(error.email) to which resolves with the list of provider IDs for that email. In this case, it will contain ['password']. You then ask the user to provide their password. You call signInWithEmailAndPassword(error.email, password) to sign-in the original user. You then call firebase.auth().currentUser.linkWithCredential(error.credential) to link the Facebook credential to the password account. Now both accounts are merged and the user can sign in with either.
I fixed it by going to the Firebase console. then head over to the authentication section and select the Settings Tab. Afterwards, go to User account linking and check Create multiple accounts for each identity provider

Automatic auth linking

On our app we are using "One account per email address". We want users to sign up using a specific authentication provider, which we keep track of, and stick with it.
What I've noticed today is that if I log in using a Google or Facebook provider I can then send myself a password reset link to the associated email address, which allows me to use the email/password provider instead.
There is a slight difference in behaviour depending on the first provider:
If I use Google first, after I use the password reset link I can now user either provider to log in, and both are linked to the same firebase uid. If I debug, I can see both in the providerDetails array on the authData object I get back from Firebase.
If I use Facebook first, after I use the password link the password provider replaces the Facebook one completely, although it retains the old firebase uid. At this point I can no longer use the Facebook login.
My questions are: is this behaviour intended, and, is there any way to switch it off?
This can cause confusion if say a user logs in using Facebook (which we track) and then later forgets and sends a password reset. It isn't the end of the world because they can carry on using the password login, but it certainly muddies the water.
Thanks
The behavior is intentional.
For end users, if they had signed into the app using Google or Facebook, and later they want to recover the password, the most likely reason is they (or an attacker) can not login with that identity provider.
After the user clicks the password reset link, Firebase removes the non-email identity providers to prevent other people from accessing the account silently. If the user still wants to add Facebook/Twitter login, they can do that via manual account linking (if the app supports).
In case the user's email service is the same as identity provider (e.g. #gmail.com users login into the app using Google), Firebase has an optimization to keep the identity provider since there is no security risk.

Lose password after sign in using Google provider

I have an Android app with use Firebase authentication using email and password. Recently added Google provider now my users can sign in wih his Google account, the problem is the following
There's an existing user example#gmail.com registered on my app, later the user sign in with his Google account Firebase automatically change the provider of the account from email to Google, the problem the user sign out and try to login with his email/password and got a message
The password is invalid or the user does not have a password
I understand why happens, but users (you know they are users) get frustrated because can't login with his email/password
There's some way to tell Firebase to keep the user password or when a user login with Google and this convertion happens in order to notify to user
Note My app only allow one account per email
I found there's a method fetchProvidersForEmail I asume I can build a flow over that method that check which provider have the user and allow the user chose if want to keep if old password by asking and linking account or just continue

Resources