Issue with Firebase with next js Authentication Flow: Unverified Email Triggers "auth/email-already-in-use" Error

53 Views Asked by At

I'm encountering a puzzling issue while implementing user registration with Firebase Authentication in my Next.js application. Specifically, when attempting to register a new user with an unverified email address, the code erroneously proceeds to the catch block and triggers an "auth/email-already-in-use" error instead of executing the intended flow to send an email verification.

Context:

I'm using Next.js for my web application development. Firebase Authentication is integrated into my Next.js application to handle user registration. The registration process involves creating a new user with an email and password. Upon successful registration, an email verification should be sent to the user. Problem:

When attempting to register a new user with an unverified email address, the code incorrectly proceeds to the catch block and triggers an "auth/email-already-in-use" error. This behavior is unexpected because the email is not already in use; it simply requires verification. Expected Behavior:

When registering a new user with an unverified email address, the code should send an email verification without triggering the "auth/email-already-in-use" error. Attempts Made:

I have verified that the Firebase project settings are correctly configured to allow unverified users. I have reviewed the Firebase Authentication documentation and ensured that the code follows best practices for handling email verification.

    const handleRegistration = async (registerData: FormData) => {
  setIsLoading(true);
  try {
    const app = initializeApp(fireconfig);

    const auth = getAuth(app);

    if (registerData.password.length < 8) {
      setPasswordErrorMessage("Password must have at least 8 characters. ");
      return;
    }

    if (passwordErrorMessage !== "") {
      setPasswordErrorMessage("");
    }

    const userCredential: any = await createUserWithEmailAndPassword(
      auth,
      registerData.email,
      registerData.password
    );
    if (!userCredential.user.emailVerified) {
      // Send email verification
      await sendEmailVerification(userCredential.user);
      toast({
        title: "Email Verification Sent. Please verify your email.",
        status: "success",
        position: "top",
        duration: null,
        isClosable: true,
      });

      const userDocRef = doc(db, "users", userCredential.user.uid);

      // Check if the user already exists in the 'users' collection
      const userDocSnapshot = await getDoc(userDocRef);

      if (!userDocSnapshot.exists()) {
        const userData = {
          firstName: registerData.firstName,
          lastName: registerData.lastName,
          email: registerData.email,
        };

        await setDoc(userDocRef, userData);
        router.push("/login");
        return;
      }
    }
  } catch (error: any) {
    if (error.code === "auth/email-already-in-use") {
      setErrorMessage("That username is taken. Try another");
    }
  } finally {
    setIsLoading(false);
  }
};
1

There are 1 best solutions below

2
Frank van Puffelen On

It sounds like the email address has already been registered with Firebase Authentication.

Calling createUserWithEmailAndPassword with an email address that has already been registered raises the auth/email-already-in-use error that you get. This is the intended behavior, because createUserWithEmailAndPassword should only be used to initially register the user. After that, you should use signInWithEmailAndPassword to sign them in.