I'm in the middle of adding firebase email/password sign in inside a React app. Specifically, it's an e-commerce site, and users will be signed in anonymously before they create an account (for things like cart data).
Here's the ideal user flow:
User registers by providing an email and password
User is not signed in immediately and instead gets a verification email
If a user tries signing in before verifying their email, they cannot sign in
User then clicks on the verification link and can sign in
I'm having issues with #3 because it appears like the only way to check if an email is verified is by calling:
const { user } = await firebase
.auth()
.signInWithEmailAndPassword(email, password)
if (user?.emailVerified) //let them enter the dashboard
However, this process signs in the user even if the email is not verified. That destroys the data on the anonymous account. And merging the two accounts isn't possible because the user thinks they are not signed in (hence it could cause UX issues if the accounts are already merged).
Any ideas?
If you're using the email+password provider, there is no way to prevent the user from signing in without a verified email address. You can of course keep them from using your app and accessing data, but you can't keep them from signing in.
If you want to ensure the user can only sign in after their email address has been verified, consider using the email link provider. You can then later allow them to set a password on the same account, either through the Admin SDK, or by creating a email+password account and linking that with the email link account. Also see the documentation on differentiating email/password from email link for some of the nuances here.
Related
My auth flow:
Firebase sendEmailVerification() needs an already authenticated user to work as the first arg.
My auth flow at the moment works like this.
Signing up the user with email and password signUpWithEmailAndPassword()
Now the firebase auth object contains the currentUser
Sending a verification mail to the just signed up user sendEmailVerification()
Logging him out and redirecting him to /email-verification where he can send the verification mail again.
Problem:
Now the problem. When the user now wants to request to send the email verification again I have three options for what I know.
Store email and password in state before logging him out -> and then logging him in again on sendAgain and logging him out afterward. Would that be a security concern?
Let him logged in the whole time. Which doesn't feel too good as he wouldn't be able to log himself out again as he officially isn't signed in till he verifies his email.
Force him to input his email and password again every time he wants to send the verification mail again, which feels redundant and old school.
If you require that the user verifies their email address in order to sign in, consider using the email link provider of Firebase Authentication.
Let him logged in the whole time. Which doesn't feel too good as he wouldn't be able to log himself out again as he officially isn't signed in till he verifies his email.
This logic may apply to your application, but it is simply not how the email+password provider in Firebase Authentication works. When the user enters the correct credentials, they are signed in to Firebase Authentication. If your app requires them to have verified their email address before they can use it, that's the exact check I'd recommend implementing.
So if you want to continue using the email+password provider, reframe the statement to:
In order to use the app, the user needs to sign in with their credentials and verify their email address.
You can then implement that in these two steps:
Ask them to sign in if they're not signed in already.
Then if the account doesn't have a verified email address, ask them to find the email and click the link - and give them to option to send another verification email.
I'm using Flutter and Firebase.
I allow new users to sign up using Email and Password, and also Apple and Google sign in.
Now I need to prevent the same user from creating an account with Email and Password, and a different account with Apple/Google sign in. As it is currently, they can create two accounts, and I see two different accounts in the Firebase console. Is there a way to make sure that once a user signed up with one method, he cannot sign up with another method? For example, check if that email already has a user associated with it?
Thanks
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 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