redshift
redshift

Reputation: 5217

Firebase Auth: How to unsubscribe from Auth observer after user creation and then subscribe again?

I am using the createUserWithEmailAndPassword() method for signing up new users. Immediately after this user creation process, I am sending an email verification. Then, in my onAuthStateChanged() I have a condition to check whether the user has verified their email. The problem is that the Auth observer is logging out the user BEFORE the email sendEmailVerification() method is complete.

Based on the below code, where is the best place to succuessfully unsubscribe the observer ? And, how to do it with Firebase JS SDK v9?

Let me explain my use case and show my code:

pages/sign-up:

async signUp() {
  const auth = getAuth()
  const batch = writeBatch(db)

  try {
    const UserCredential = await createUserWithEmailAndPassword(
      auth,
      this.formValues.email,
      this.formValues.password
    )
    
    const userDocRef = doc(db, 'users', UserCredential.user.uid)
    batch.set(userDocRef, {
      uid: UserCredential.user.uid,
      displayName: this.formValues.displayName,
      photoURL: `https://gravatar.com/avatar/${md5(
        this.formValues.email
      )}?d=identicon`
    })
    const usernameDocRef = doc(db, 'usernames', this.formValues.displayName)
    batch.set(usernameDocRef, { uid: UserCredential.user.uid })

    // Commit batch
    await batch.commit()
    console.log('batch committed, user is:', UserCredential.user.uid)
    await this.verifyEmail() // <-- user is logged out before this has a chance to fire!

verifyEmail():

async verifyEmail() {
  const auth = getAuth()
  const actionCodeSettings = {
    url: `${this.$config.baseUrl}/email-confirmation/success`
  }
  try {
    await sendEmailVerification(auth.currentUser, actionCodeSettings)
  } catch (error) {
    console.error('An email verification error happened', error)
    this.errorMessage = error.message
  }
},

In my onAuthStateChanged() method, I am immediately logging out the user IF their email is not yet verified. This causes the following error:

enter image description here

And here is how I have my onAuthStateChanged observer set up (it runs before the page is rendered):

~/plugins/auth.js:

onAuthStateChanged(auth, (user) => {
  if (user) {
    if (!user.emailVerified) {
      // User has not verified the email yet
      store.dispatch('logOutUser')
    }
  // TO DO: finish up rest of user logic

Should the unsubscribe be in the auth.js or the pages/sign-up page? I am unsure how to unsubscribe.

Upvotes: 1

Views: 512

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50840

If you need to perform certain actions after signup/login, then you should unsubscribe from auth observer as you've figured out.

const authObserver = onAuthStateChanged(auth, (user) => {
  // ...
}

async signUp() {
  //unsubscribe here i.e when user clicks signup button
  authObserver() 
 
  const auth = getAuth()
  const batch = writeBatch(db)
  // ...
}

Do note that, if you you auth observer is meant to redirect logged in user somewhere else then it won't do it now. So make sure you do that manually.

Upvotes: 1

Related Questions