Firebase Authentication - users not receiving verification emails - firebase

I have built an app that uses email & password authentication from Firebase, to enable users to log in, as per the Firebase documentation. The app itself uses Flutter as the coding language. I also have email verification enabled, to prevent spam accounts.
When a user adds their email address and password and clicks 'submit', they're given a notification telling them to check their emails for the verification link, which they must do before being allowed to log in.
The problem I am having is that users do not receive the verification email, so cannot log in. I've come across similar questions on this forum, where the answers have centred around checking spam/junk folders. I have asked the users to do this but they still have not received the email.
I've also tried using my own SMTP server, which is one from which I know I can send emails. Even with this, the users do not receive their verification email. This makes me think the emails aren't being generated/sent, as opposed to them being sent and not being received.
Can anyone suggest why this might be the case? Why is it that users are not receiving the verification email and what can I do to correct this?

If you don't use custom domain, sometimes emails go in spam folder

Related

Firebase reset password not sending link to email in Firebase Console [duplicate]

I am new to firebase and I am trying to handle firebase user authentication in React.js. I did manage to create users with email and passwords. But, now I would like to send the user an Email link to reset their password.
My code currently look like this.
// This line of code belongs to the top
import { auth } from '../firebaseConfig'
//This part goes under the React component
<p onClick={async () => {
try{
await sendPasswordResetEmail(auth, // My Email Id)
alert('Password reset link has been sent to your email')
}
catch(err){
alert(err)
}
}}
>Forgot your Password ?</p>
However, I do not get any error messages and I do get the alert message that says "Password reset link has been sent to your email." Unfortunately, I didn't receive any email. Note that I have given my own email id as the parameter for testing purposes.
firebaser here
Did you check your spam folder? We recently see a lot of the emails from Firebase Authentication ending up in the user's spam folder or being marked as spam in a system along the way. This is being tracked in this status message on the Firebase dashboard and in public issue #253291461.
To reduce the chances of the messages getting marked as spam, consider taking more control of the email delivery yourself.
As a first step, consider using a custom domain with your project. Email that comes from a custom domain has less chance of being marked as span.
As a second step, consider setting up your own SMTP server.) for delivering the email, so that the emails are not being delivered from Firebase's shared infrastructure anymore.
While these steps are more involved, they typically will drastically reduce the cases where the messages from Firebase Authentication are marked as spam.
Full Guide Based on Frank's Answer
Firstly create a new email account you can use to relay the Firebase emails through the SMTP server with. I personally chose Gmail, but I tested with Outlook and it also works.
You can now find an SMTP server host that will work for your scenario. If you're sending less than 1000 emails per month you can find free and reliable hosts. I chose SMTP2GO's free option.
Now you've found the SMTP host, add the email address you've chosen as a single sender email (note that if you do own a domain, you can alternatively use that to send emails).
Note that you will have to verify the email, usually by your host sending a link to the email's inbox. Make sure to check spam.
Once verified, navigate to where you host allows you to add SMTP Users and add a new user. This will allocate an SMTP username and password.
Navigate to the Firebase console, and choose the Authentication option from the sidebar (within the Build product category).
Go to Templates → SMTP Settings and enter the details of your SMTP server. The username and password fields are to be filled with the SMTP user login you created in the step above.
It is better to use TLS, but I believe SSL should work too but it is untested.
Click save, and you're all set up - but there may still be steps to perform depending on your email provider.
Provider Specific Steps
If the emails are being sent to an account managed by Google you will have no issues with your emails being quarantined by anti-spam policies and it will work immediately.
If you are using Outlook, you will have a different problem on your hands. Outlook's built in defender will most likely have auto-quarantined your email under multiple policies - that bit is important.
These policies are likely to be both spam and phish policies. If you unblock one of them, the other will catch it and re-quarantine.
Unblock both policies for the email address, and test. You can see the status of quarantined messages in Microsoft 365 Defender app under Review → Quarantine. Please note that you will need to be an administrator to add global allow policies to your email accounts.
If this still doesn't work it is likely that your company has an additional external filter (as mine did), and you will have to add the IP's manually to the Tenant Allow/Block Lists spoofed senders tab.

What is the best practice for firebase resending sendEmailVerification()?

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.

Firebase not sending emails?

I can't get Firebase to send verification emails, anyone with the same issue?
I've created an account, enabled Email/Password, and added users.
However, when I go to the Users tab in Authentication, chooses a user and presses Reset password, Firebase tells me, that the email is send, however I never receive it?
I've tried with multiple different emails (gmail, hotmail etc) and looked through spam etc, however I never receive the email. What am I doing wrong? Some setting somewhere I need to tick-off? Rookie question, I know, but frustrating. Thanks!!
I get the same problem with an user, he didn't receive any email with his work email address from Firebase magic link authentication.
I'm still using Firebase as provider but I think to integrate with sendgrid soon.

Is it Possible? sending email verification before a record is created in firebase authentication? [duplicate]

This question already has an answer here:
Verify a user's email address before confirming registration, with Flutter and Firebase
(1 answer)
Closed 1 year ago.
Is it Possible? can I send email verification before I create a user with email and password in Firebase authentication using flutter?
I wanted to know this because if I register the entered mail and then if I send email verification, then if the email account is not valid(i.e the email format is correct, but it is not present in google database to send link to email), then it would simply create a record in Firebase authentication which is a loss of storage, so I would like to know.
Thank you
There are two providers for signing in with email to Firebase:
Through Email+password. There is no way to require the user to verify their email address before they can sign in with this provider. You can of course prevent users without a verified email address from using the app, and accessing the data.
Through Email link. Here the user gets an email with a sign-in link, so their email address is implicitly verified as part of signing in.
If you want to require the user to verify their email address before they can sign in, it might be best to have them sign in through an email link.
In addition to #Frank's answer, when a user signs up you can send verification email to them. You can always check if the user has verified their email in your app by checking the isEmailVerified property as well as in security rules.
Talking of database storage, you can run a scheduled cloud function every midnight to delete data of users who have not verified their email.
You can refer to this answer for a detailed explanation on periodically deleting unverified users.

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.

Resources