notGoodAtThis
notGoodAtThis

Reputation: 51

Failing to catch Firebase authentication error for duplicate emails

I am using Firebase v10 for authentication on my React web app. I am able to create a user and log in, thus authentication is working, however, if a new user tries to enter an email which already exists in my database, the error sent back from Firebase is not being caught in my code (although firebase is sending back an error in console and it is not adding the duplicate user to the database as intended).

I am using an Authentication context JavaScript file, which calls the Firebase create user method, and I am referencing the context in a sign up page.

My context code

const AuthContext = createContext()

export function useAuth() {
    return useContext(AuthContext)
}

export function AuthProvider({ children }) {

    const [currentUser, setCurrentUser] = useState()
    const [loading, setLoading] = useState(true)

    function signup(email, password) {
        methods.createUserWithEmailAndPassword(auth, email, password).then(cred =>{
            if (cred !== undefined){
                let userType;
            if (email.substring(email.indexOf('@') + 1) === "sun.ac.za"){
                userType = "student";
            }
            else{
                userType = "company";
            }
            let data = {
                email: cred.user.email,
                type: userType
            };
            setDoc(doc(users, cred.user.uid), data);
            }            
          }       
          )
    }

My sign in page's function for handling the form submit

 async function handleSubmit(e) {
        e.preventDefault();

        if (!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(emailRef.current.value))) {
            return setError("Please enter a valid email address.");
        }

        if (passwordRef.current.value.length < 6) {
            return setError("Please enter a password of at least 6 characters.");
        }

        if (passwordRef.current.value !== passwordConfirmRef.current.value) {
            return setError("Passwords do not match.");
        }


        try {
            setError("")
            setLoading(true)
            await signup(emailRef.current.value, passwordRef.current.value)
        } catch (e) {
                return setError("Cannot create an account.");
            }
            setLoading(false);
            navigate('/');
    }

Upvotes: 0

Views: 274

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83153

You need to return the Promises chain in the signup function, as follows:

export function AuthProvider({ children }) {

    const [currentUser, setCurrentUser] = useState()
    const [loading, setLoading] = useState(true)

    function signup(email, password) {
       return methods.createUserWithEmailAndPassword(auth, email, password).then(cred =>{
            if (cred !== undefined){
                let userType;
            if (email.substring(email.indexOf('@') + 1) === "sun.ac.za"){
                userType = "student";
            }
            else{
                userType = "company";
            }
            let data = {
                email: cred.user.email,
                type: userType
            };
            return setDoc(doc(users, cred.user.uid), data);
            }            
          }       
          )
    }

Upvotes: 2

Related Questions