28

I wish to create a user account in Firebase Auth using createUserWithEmailAndPassword() - without logging in the user. I wish for the user to verify the email address first. Signing in the user directly causes a lot of unwanted side effects.

The /signup page has the following code - I wish for the user to stay on the /signup page after registration to be able to see the registration message.

firebase.auth().createUserWithEmailAndPassword(data.email, data.password)
.then((user)=> {
  //Send email verification link
  user.sendEmailVerification()
  //Show message - "Your account was created - please verify using link in email"
  handleStatusMessage(AUTH_SUCCESS)
})
.catch((error)=>{...})

The app.js has the following login and redirect handler

//handle login and redirect
firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    if(!user.emailVerified){
      //Exit if email is not verified
      console.log('auth.js exit')
      //Line 7
    }
    store.dispatch(setInitialStore()).then(() => {
      renderApp()
      //Brings user to start page
      if (history.location.pathname === '/login') {
        history.push('/start')
      }
    })
} else {
  renderApp()
  //Brings user to /login or /verifyEmail page when logged out
  if(!history.location.pathname.includes('/verifyEmail')){
    history.push('/login')
  }  
}

My problems are:

  1. The user gets redirected after successful signup unless I cancel execution on line 7

  2. If I cancel execution on line 7, the user gets stuck when moving away from /signup

  3. Logging out the user causes the onAuthStateChanged() to trigger twice - redirecting the user

How can I keep the user on the /signup page after successful account creation while still allowing the user to navigate to the /login /verifyEmail location? Preferably in logged out state.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Kermit
  • 2,865
  • 3
  • 30
  • 53
  • `createUserWithEmailAndPassword` automatically signs the user in upon successful account creation, so your only option would be to immediately sign them out again. – Herohtar Sep 02 '19 at 21:17
  • Hi @Herohtar! Signing the user out again triggers onAuthStateChanged() twice - I will need to handle two cases to prevent the user from being redirected and logged in. Logging the user out is a good idea though, since I wish not for the user to be logged in. – Kermit Sep 03 '19 at 07:24

3 Answers3

24

What I ended up doing was adding checks for when the user was logged in and logged out during signup.

signupPage.js

firebase.auth().createUserWithEmailAndPassword(data.email, data.password)
.then((user)=> {
  //Login is triggered --> line 4 in app.js
  user.sendEmailVerification() //Send email verification
  handleStatusMessage(AUTH_SUCCESS) //Show success message
  firebase.auth().signOut() //Logout is triggered --> line 16 in app.js
})
.catch((error)=>{ ... }

app.js

//handle login and redirect
firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    //** line 4 ** EXIT if logged in from /signup
    if(!isEmailVerified && history.location.pathname.includes('/signup')){
      return
    }
    store.dispatch(setInitialStore()).then(() => {
      renderApp()
      //Brings user to start page
      if (history.location.pathname === '/login') {
        history.push('/start')
      }
    })
} else {
  //** line 16 ** EXIT if logged out from /signup
  if(history.location.pathname.includes('/signup')){
    return
  }
  renderApp()
  //Brings user to /login or /verifyEmail page when logged out
  if(!history.location.pathname.includes('/verifyEmail')){
    history.push('/login')
  }  
}

I really wish there was a option for createUserWithEmailAndPassword() to be able to automatically send the email verification email and not logging in the user to avoid this kind of cat-and-mouse game code. :)

A separate method along the lines of createUserWithEmailAndPasswordEmailVerificationRequired() that automatically sends the email link and does not sign in the user would also work ;)

Kermit
  • 2,865
  • 3
  • 30
  • 53
  • 1
    I added a feature request for this. Please upvote it to bring more attention to this problem: https://github.com/FirebaseExtended/flutterfire/discussions/5692 – jon Apr 07 '21 at 17:51
  • so still no changes here? what a mess – Ruben May 11 '23 at 20:37
12

The Firebase Auth function createUserWithEmailAndPassword automatically signs in users upon successful account creation (which does not require email verification).

If you need to verify email addresses for new user sign-ups without automatic sign-in, then an alternative is Email Link Authentication.

You can use Firebase Authentication to sign in a user by sending them an email containing a link, which they can click to sign in. In the process, the user's email address is also verified.

There are numerous benefits to signing in by email:

  • Low friction sign-up and sign-in.
  • Lower risk of password reuse across applications, which can undermine security of even well-selected passwords.
  • The ability to authenticate a user while also verifying that the user is the legitimate owner of an email address.
  • A user only needs an accessible email account to sign in. No ownership of a phone number or social media account is required.
  • A user can sign in securely without the need to provide (or remember) a password, which can be cumbersome on a mobile device.
  • An existing user who previously signed in with an email identifier (password or federated) can be upgraded to sign in with just the email. For example, a user who has forgotten their password can still sign in without needing to reset their password.

After users successfully created accounts via email link authentication, you could provide the option to create a password and link to the existing account.

Community
  • 1
  • 1
Christopher Peisert
  • 21,862
  • 3
  • 86
  • 117
  • 2
    Hi @christopher! Thank you for the reply! I am aware of the Email Link Auth option but wish not to use that method. I could be a good alternative for someone else though. I think the lacking option for email verification on email + password signup is something that could be improved in firebase auth. – Kermit Sep 03 '19 at 07:27
  • The ability to first log in using a email link and then set a password + link the account is something I might consider in the future! – Kermit Sep 03 '19 at 08:08
0

As of July 2023, it is still not possible to send a verification email before the user is signed in.

I've tried several approaches, including the blocking functions. It is not possible to generate the verification link before the user is signed in for the first time.

The only way is to signed them out right after they're registered + signed in (1st sign-in, happens simultaneously with the sign-up).

BUT the important thing to note here is that anyone can (obviously) modify the client code. So you must protect your data and check if the email is verified before you let them use any resource.

I go more in depth in my recent Ultimate Guide to User Authorization with Identity Platform. See the Protect Data section.

Michal Moravik
  • 1,213
  • 1
  • 12
  • 23