72

I've set up Firebase email/password authentication successfully, but for security reasons I want the user to confirm her/his email. It says on Firebases website:

When a user signs up using an email address and password, a confirmation email is sent to verify their email address.

But when I sign up, I doesn't receive a confirmation email.

I've looked and can only find a code for sending the password reset email, but not a code for sending the email confirmation.

I've looked here:

https://firebase.google.com/docs/auth/ios/manage-users#send_a_password_reset_email

anyone got a clue about how I can do it?

Benja0906
  • 1,437
  • 2
  • 15
  • 25

8 Answers8

129

I noticed that the new Firebase email authentication docs is not properly documented.

firebase.auth().onAuthStateChanged(function(user) {
  user.sendEmailVerification(); 
});

Do note that:

  1. You can only send email verification to users object whom you created using Email&Password method createUserWithEmailAndPassword
  2. Only after you signed users into authenticated state, Firebase will return a promise of the auth object.
  3. The old onAuth method has been changed to onAuthStateChanged.

To check if email is verified:

firebase.auth().onAuthStateChanged(function(user) { 
  if (user.emailVerified) {
    console.log('Email is verified');
  }
  else {
    console.log('Email is not verified');
  }
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Xavier J. Wong
  • 1,411
  • 1
  • 11
  • 3
  • Thank you, I've been looking for this answer, Do you know how to check if the email has been confirmed? – Benja0906 May 25 '16 at 09:28
  • 2
    firebase.auth().onAuthStateChanged(function(user) { (user.emailVerified) ? console.log('Email is verified') : console.log('Email is not verified') }); – Xavier J. Wong May 25 '16 at 09:33
  • Thank you, this was very helpful :) – Benja0906 May 25 '16 at 12:44
  • 1
    *firebaser here* Great answer @XavierJ.Wong. I added a note that we need to add this to the documentation. – Frank van Puffelen May 25 '16 at 13:59
  • 6
    @FrankvanPuffelen Still not in the docs. It is nicely stated in the auth email templates page, yet there's no documentation anywhere on it, except this answer. – KhoPhi Jun 18 '16 at 17:32
  • Same! Thanks for this answer. I can't believe this isn't in the docs. – SeBsZ Sep 23 '16 at 10:38
  • @XavierJ.Wong Can you please provide the link for rest of the documentation? – Umer Farooq Jul 15 '17 at 10:47
  • So your saying every time the authStateChanges you want to send an email? – Oliver Dixon Dec 14 '17 at 11:04
  • @OliverDixon authStateChanges refers to an observer on the Auth object, as it is usually not immediately available during initialization. Sending the email in this sense is to answer the original question of sending the email verification automatically via Firebase functions on the returned User object. – Xavier J. Wong Dec 25 '17 at 04:06
  • Can I ask is this a good approach to having a persistent session on a react-native app? By invoking onAuthStateChange in your main App.js or dispatch to a saga function? – Michael Mar 13 '18 at 16:26
  • 1
    @FrankvanPuffelen I've never understood how, but people can create "google.com" accounts with non-Google email addresses - and the `emailVerified` flag will return false but attempting to `sendEmailVerification` won't do anything. Is there any way to differentiate this case so that we can ignore the verification state - or is this a bug in Firebase? – andygeers Sep 04 '19 at 09:30
  • "You can only send email verification to users object whom you created using Email&Password method createUserWithEmailAndPassword" I think this should be updated, I'm successfully using email verification with Microsoft accounts. I believe the email verification should work with any user that's not already `emailVerified` and that has a valid email configured in Firebase auth – Val Mar 16 '23 at 22:08
13

After creating a user a User object is returned, where you can check if the user's email has been verified or not.

When a user has not been verified you can trigger the sendEmailVerification method on the user object itself.

firebase.auth()
    .createUserWithEmailAndPassword(email, password)
    .then(function(user){
      if(user && user.emailVerified === false){
        user.sendEmailVerification().then(function(){
          console.log("email verification sent to user");
        });
      }
    }).catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;

      console.log(errorCode, errorMessage);
    });

You can also check by listening to the AuthState, the problem with the following method is, that with each new session (by refreshing the page), a new email is sent.

firebase.auth().onAuthStateChanged(function(user) {
  user.sendEmailVerification(); 
});
tdhulster
  • 1,531
  • 3
  • 18
  • 32
  • 3
    `sendEmailVerification()` after `createUserWithEmailAndPassword` is not working. At that time `user.emailVerfied` is `undefined`. Sending email should always happen `onAuthStateChanged` – sungyong Mar 19 '19 at 08:29
  • 5
    The callback for `createUserWithEmailAndPassword(...).then` receives a `firebase.auth.UserCredential`, not a `firebase.User`. Just use `then(credential => credential.user.emailVerified ... )` instead. – Andy Apr 09 '19 at 09:36
  • 2
    @Andy : According to the [Firebase Doc here](https://firebase.google.com/docs/auth/admin/manage-users#create_a_user), I use `then((userRecord) => { userRecord.user.sendEmailVerification()... })`, but it says `Cannot read property 'sendEmailVerification' of undefined`. – Antonio Ooi Jun 20 '20 at 20:09
11

The confirmation email could be in your spam folder. Check your spam folder.

Hussein Hn
  • 169
  • 1
  • 8
5

You can send verification email and check if was verified as follow into the AuthListener:

mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();

            if (user != null) {

//---- HERE YOU CHECK IF EMAIL IS VERIFIED

                if (user.isEmailVerified()) {
                    Toast.makeText(LoginActivity.this,"You are in =)",Toast.LENGTH_LONG).show();
                } 

                else {

//---- HERE YOU SEND THE EMAIL

                    user.sendEmailVerification();
                    Toast.makeText(LoginActivity.this,"Check your email first...",Toast.LENGTH_LONG).show();
                }

            } else {
                // User is signed out
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
            // [START_EXCLUDE]
            updateUI(user);
            // [END_EXCLUDE]
        }
    };
Pablo Prado
  • 63
  • 1
  • 4
2

if you're using compile "com.google.firebase:firebase-auth:9.2.0" and compile 'com.google.firebase:firebase-core:9.2.0' the method sendEmailVerification() will not be resolved until you update to 9.8.0 or higher. It wasted most of time before I figured it out.

MbaiMburu
  • 875
  • 1
  • 10
  • 19
1

I have been looking at this too. It seems like firebase have changed the way you send the verification. for me

user.sendEmailVerification() 

did not work. If you get an error such as user.sendEmailVerification() doesn't exist. use the following.

firebase.auth().currentUser.sendEmailVerification()
David Innocent
  • 606
  • 5
  • 16
1

It's not the answer to the question but might help someone. Don't forget to add your site domain to the Authorised domains list under Sign-in-method

Binod Kafle
  • 89
  • 1
  • 4
0

You could send a verification email to any user whose email is linked to the Firebase Auth account. For example, in Flutter you could do. something like :

    Future<void> signInWithCredentialAndLinkDetails(AuthCredential authCredential,
        String email, String password) async {
      // Here authCredential is from Phone Auth
      _auth.signInWithCredential(authCredential).then((authResult) async {
        if (authResult.user != null) {
          var emailAuthCredential = EmailAuthProvider.getCredential(
            email: email,
            password: password,
          );
          authResult.user
              .linkWithCredential(emailAuthCredential)
              .then((authResult,onError:(){/* Error Logic */}) async {
            if (authResult.user != null) {
              await authResult.user.sendEmailVerification().then((_) {
                debugPrint('verification email send');
              }, onError: () {
                debugPrint('email verification failed.');
              });
            }
          });
        }
      });
    }
martn_st
  • 2,576
  • 1
  • 24
  • 30
sjsam
  • 21,411
  • 5
  • 55
  • 102