Firebase authentication only converts Facebook and Email auth to Google auth, But Not vice versa - firebase

I knew it is raised already, but i want to clear and sum it up.
I use FireBase authentication to allow the following Sign Up:
Facebook
Google
Email
When signed up with Email, but later decide you want to change credential to Facebook (Having the same email) You receive an error. Same issue from Google to Facebook.
The Error:
An account already exists with the same email address but different
sign-in credentials. Sign in using a provider associated with this
email address.
However, if you Logged with Facebook or Email you CAN change your credential to Google.
Theoretically you can allow multiple accounts with the same email:
However, it means (from what i understood) Firebase auth will generate a unique UserID for each additional credential which means that if you use UserID to track data of user (messages, score, etc..) you need somehow track all UserIDs from all credentials. This can ruin one of Firebase authentication purposes.
If you decide to go this way, you will need to link the accounts using LinkWithCredentialAsync. As i understood this can be ONLY be done if you are LOGGED IN with your other credential.
I rising this because i was disappointed to discover this only after implementing Firebase.
The solution from this thread Stackoverflow thread is creative (see pupadupa scheme), but i do not want to go this way.
If someone can add on to this and found some sort of solution, please post it.

Related

How to link EmailAuthProvider with FacebookAuthProvider in firebase

I try to merge email/password account with Facebook account. The scenario is like:
user created an account in my app (email/password provider)
one week later, he can't remember that he created his account with Google or Facebook or Email/Password, so he clicks to sign in with Facebook.
an error message appears auth/account-exists-with-different-credential - that's ok, understand that.
fetchSignInMethodsForEmail sends me 'password' provider with flag isOAuthProvider: false which means I can't directly sign in with FB.
What should I do next to log in with Fb and then link that account with existed email/password account of that user?
Should I redirect the user to email/password form and tell him (toast) why should he try to log in this way, or there is a better solution?
After the steps you've described, I see two logical options:
Indeed let the user complete the sign-in with Facebook, and sign-in with their email/password, and then link those accounts.
Tell them that they signed in with email/password before, and redirect them to that.
Linking the accounts is typically a nicer flow for the user, but it is more work to get working.

Limit each firebase user to only one auth provider?

How do I make it so that when a new user signs up in firebase, they can only login with that provider? Ex: a new user uses an email and password to sign up and then is rejected when trying to log in with Google.
I'm using Firebase with javascript in React if it helps.
What you're asking doesn't sound possible. The different auth providers don't know about each others' user bases. jackoboy on Google isn't at all related to jackoboy on Facebook. While they might have the same email address, that's never a guarantee that they are the same individual. So when jackoboy signs up with Google, there is nothing that can possibly stop jackoboy from also signing up with Facebook as a different account.
If you want to impose your own checks to see if the end user might be the same, you're going to have to write some code for that on a backend you control, then delete the second account if it appears to be the same person, by whatever logic you determine. Firebase Auth just isn't going to do that for you.

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 recover password transforms account type

we are building an angular 5 app with Firebase.
We allow users to login with email+password or google account and we don't allow to have multiple accounts related to the same email address.
We built a form to allow users to ask for a Password Reset Email if they forgot their email password credentials and works perfectly if the user has an email+password account.
The problem arises when the reset email is asked for a google account. We'd expect for firebase to throw an error, not allowing to send the email, but the email is sent and if the user proceeds resetting the email the account is transformed from google type to an email+password.
Is there a way to prevent this behaviour ?
There is no way to prevent this. When a user resets their password, they are making a conscious decision to do so. Firebase is providing a way to recover an email account, in case it was hijacked. In the process all providers are unlinked and a password is set on the account.
You have a way to check if the email is associated with google provider or not. Checkout the fetchSignInMethodsForEmail and fetchProvidersForEmail APIs. These APIs would return the array of sign in methods or providers associated with an email.

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.

Resources