Would anyone know how we could implement the following with Firebase auth. Docs/searches haven't produced a good answer yet. So the use case is as follows:
User comes to a site to buy something. We allow them to buy without any sign-up barrier and on checkout, just ask them for their email. An anonymous user is created and their purchase is sent to their email provided.
With that email, we'd like to set up a passwordless account for them so that the user can log in later just with their email and see items bought in their dashboard. For that the anon uid recorded with the purchase needs to be associated with the email.
So the question is how to achieve that an anon account upgraded to a registered account with the email provided.
We've tried inserting a passwordless sign-in link sending at the point of the purchase, but it just created a new account with a new id, which is not what's needed. We need the uid to stay the same as the anon user's so that we can simply connect their purchases to the newly email-authenticated account. Perhaps, there is a way of associating an anon uid with an email before sending that passwordless signin link?
Hope this makes sense, but please do ask if anything is unclear.
To create a Credential object from an email link, you can use the EmailAuthProvider.credentialWithLink method. You can then use this credentials object to upgrade your anonymous account.
Also see: Deleting User account with using Passwordless Authentication?
Related
In a Firebase project, I have activated multiple sign-in methods (e-mail, Google, and Microsoft), which all work fine. I also have it activated to only allow one account per e-mail address.
The problem arises when a user successfully signs in via Google or Microsoft, then signs out and then signs in via e-mail, using the same e-mail address as before using Google or Microsoft. Then his account type changes to e-Mail and it seems like a no way back.
Is there a way to change user account types from e-mail back to Microsoft or Google?
Your code must have different functions written for different signin's. When the user first logs in, store his login method on firestore. You can get this from the signin function triggered or simply by the button user clicked. Then during each login add a check that if user exists and user's current signin method is not the same as the one stored on firestore, notify the user to use the correct one.
Or you can let the user signin using whatever they please but ultimately in your code, the function which is triggered will tell you the current signin method and you'd have the first/previous method stored. So you can do stuff accordingly.
What you are writing in question seams not how it works. When you sign in using Google provider your email is verified automatly and if you try to sign in using same email authentication will throw error that account with that email allredy exists.
If you created first account using email and password and didn't verify your email addres then if you sign in using google provider with same email address in it, email and password provider will gone because of was not verified and you wont be able to login using email end password unless you will setup a new password for this email.
If email was verified and you sign in using google provider with same email address. This provider will be added to providers array and you will be able to login using email and password and google provider.
To add multiple providers to your accaunt you can use linkWithPopup() function. If you created accound with diferent email address and want to be able to log in on this account with provider who has diferent email address for example.
Has anyone managed to associate an authorised email to an anon UID that was created earlier on another device?
Here is the workflow:
User comes to the site for the first time, anon UID is created, they enter email as part of signup, which is added to their details in the db
An email is sent to them to verify the email.
However, user misses it for whatever reason.
Instead, they come again with a different device and try to log in using a password-less login by entering their email and receiving a link
they get the link and click on it. The email gets verified, but gets assigned to a NEW UID created on the 2nd visit.
The question is how can the email be linked to the 1st UID instead of the 2nd one on a new device?
Under 2, before the email is sent, I am calling firebase.auth().currentUser.updateEmail(email), but it doesn't seem to associate the email with the UID in the firebase for some reason. I can see that in the Firebase Authentication tab -- the UID is still showing as Identifier (anonymous). This is probably the root cause of the issue as otherwise the email would be there, just unauthenticated.
Any ideas would be welcome!
Setting an email address to an anonymous account doesn't change its provider to suddenly become email+password. It remains an anonymous account, it now just also has an email address associated with it. To associate the user with an email+password account, you'll have to sign them in with email+password credentials and then link those credentials to the existing anonymous account.
To link accounts/providers, you must create credentials for both providers on the same device and call the relevant API to link them.
Since you only have a UID from anonymous sign-in on the first device, that UID can't be recreated on the second device. And that means there is no way to link the email-link UID account on the second device to the anonymous UID on the first device.
In my app, if a user registers using email and password, but later tries to log in or register using a Google account that shares that email, the account gets converted to a Google account and the user can no longer sign in with their email and password. I've configured the project with One account per email address setting on.
Is there any way of preventing this?
This is the expected behavior as Google accounts are verified: Firebase Overwrites Signin with Google Account
There are 2 ways around this:
1. Verify emails of password users. Google provider will be added to the account without unlinking the password if the user is verified.
2. You will need to switch to "multiple accounts per email", but this means 2 accounts will be created here, one email/password and another for Google.
I recommend the first approach. Firebase Auth does this for security reasons. Any person can claim an email. Unless the ownership is verified, the password must be unlinked to prevent the impersonator from gaining access to the account.
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.
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