1

In my app I want to signout the user after creating user with email inorder to verfiy his email. I tried different methods but they aren't working. Here is my code:

try {
          await app
            .auth()
            .createUserWithEmailAndPassword(email.value, password.value)
            .then((userCredential)=>{
              // send verification mail.
              userCredential.user.sendEmailVerification();
              alert("Email sent");
            })
            .catch(alert);
            //history.push("/");
        } catch (error) {
          alert(error);
        }

I have imported firebase initalizer from another component:

import firebase from "firebase/app";
import "firebase/auth";

const app = firebase.initializeApp({
  apiKey: process.env.REACT_APP_FIREBASE_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
});

export default app;

Here is my authcontext:

useEffect(() => {
    app.auth().onAuthStateChanged((user) => {
      setCurrentUser(user);
      setPending(false);
    });
  }, []);

  if (pending) {
    return <>Loading...</>;
  }

  return (
    <AuthContext.Provider
      value={{
        currentUser,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

Any ideas on this?

axfg
  • 65
  • 10

1 Answers1

1

You can try using the signOut method to log the user out:

// unsubscribe Auth listener here
return app.auth()
         .createUserWithEmailAndPassword(email.value, password.value)
         .then(async (userCredential)=>{
           // send verification mail.
           await userCredential.user.sendEmailVerification();
           await app.auth().signOut();
           alert("Email sent");
         })

Although you don't need to log the user out if their email is not verified (depends on how you want your app to work but just a note). You can simply check if the email is verified, if not then prompt the user to verify it else do not allow them to use the app.

The User object has a property emailVerified to do so:

if (!app.auth().currentUser.emailVerified) {
  alert("Please verify the email")
}

You can also check if the email is verified in security rules:

match /{document=**} {
      allow read, write: if request.auth != null && request.auth.token.email_verified;
}
Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
  • I tried your first solution before but it isn't working. – axfg Jun 30 '21 at 07:34
  • @axfg please try updated answer. I had missed the promises. Please add the async and await as mentioned. – Dharmaraj Jun 30 '21 at 07:36
  • It's working. Thank you so much. But it is showing the private route for a second before kicking the user out. How to overcome that? – axfg Jun 30 '21 at 07:41
  • @axfg please share your code that deals with changing routes. I doubt you have a onAuthStateChanged listener by chance? If the original question is resolved, feel free to accept the answer :) [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers) – Dharmaraj Jun 30 '21 at 07:43
  • I use authcontext ,inside it I have onauthstatechanged. How to deal with it? – axfg Jun 30 '21 at 07:46
  • @axfg I can't really check what is going on. Can you please share your complete code and explain what's not working? [Gist](https://gist.github.com) might help – Dharmaraj Jun 30 '21 at 07:47
  • I've edited the question and added the authcontext. Check it. – axfg Jun 30 '21 at 07:50
  • @axfg so whenever the auth state changes (users logs in or signs out), that function is triggered and because of that `setCurrentUser()` and `setPending()` are being invoked too. In this case they ideally shoudn't. Please check [this](https://stackoverflow.com/a/68175518/13130697) answer on how to unsubscribe from them. – Dharmaraj Jun 30 '21 at 07:52
  • I didn't get it. Can you explain it a bit? – axfg Jun 30 '21 at 07:57
  • @axfg the `onAuthStateChanged` will run whenever a user logs in (in your case, a new user account is created) and that is causing `setCurrentUser` function to run. You haven't posted the code for that function but I am assuming that function redirects user to a secured route? – Dharmaraj Jun 30 '21 at 07:59
  • yes. I know it's triggering the setCurrentUser. What is the workaround for this? or is your second solution more appropriate for this? – axfg Jun 30 '21 at 08:01
  • @axfg check the answer that I had shared above. There's another answer from @ Frank which explains how to unsubscribe from the listener – Dharmaraj Jun 30 '21 at 08:04
  • Ok thank you. What about using emailverified method? – axfg Jun 30 '21 at 08:10
  • @axfg I've added a comment in my answer, unsubscribe from the listener there and then keep the rest of the code same – Dharmaraj Jun 30 '21 at 08:11
  • Sorry to be so naive. What is meant by unsubscribe? – axfg Jun 30 '21 at 08:22
  • @axfg by unsubscribe I mean stopping that 'auth state changed' listener. Essentially the code inside of that won't run on any events. (Just like you won't get any notifications from youtube when someone posts a video but you've unsubscribed from the channel) – Dharmaraj Jun 30 '21 at 08:38
  • I have added a question [here](https://stackoverflow.com/q/68191153/16334669). You can also add your answer there. – axfg Jun 30 '21 at 08:45