0

I have an auth.js file that runs to authenticate users that handles sign up/sign in for email, google, and facebook. Im having trouble getting redirect result after google users log in with redirect. Once I am redirected, I expected the function to write data to firestore and then redirect me to another page. It instead returnes the error undefined to the console.

Here is the code:

function signInWithGoogle(){
    signInWithRedirect(auth, googleProvider);
}

// Get rediresct result
getRedirectResult(auth)
.then(async (result) => {
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const token = credential.accessToken;

    const user = result.user;
    const q = query(collection(firestore, "users"), where("uid", "==", user.uid));
    
    // Make a snapshot of the current user data
    const querySnapshot = await getDocs(q);
    // If the doc is empty, write new data. Else, update it
    if (querySnapshot.empty){
        const docRef = await addDoc(collection(firestore, "users"), {
            uid: user.uid,
            role: "Student",
            last_login: dt,
            fname: null,
            lname: null
        });
        // Go to profile.html
        goToUrl("profile.html");
    } else {
        // If there is already a document, update the last login property
        querySnapshot.forEach(async (document) => {
            const docReference = doc(firestore, "users", document.id);
            
            await updateDoc(docReference, {
                last_login: dt
            });
        });
        // Go to profile.html
        goToUrl("profile.html");
    }
}).catch((error) => {
    console.log(error.code);
});
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121

1 Answers1

2

You don't indicate at which line the error occurs so it is not easy to understand what is the error cause...

However you are mixing then() with async/await which is not recommended and you use forEach() with await which does not work as you expect (see "JavaScript: async/await with forEach()" and "Using async/await with a forEach loop").

You most probably have only one user doc corresponding to an uid so you could adapt your code as follows:

const result = await getRedirectResult(auth);
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;  // <= Not needed

const user = result.user;
const q = query(collection(firestore, "users"), where("uid", "==", user.uid));

// Make a snapshot of the current user data
const querySnapshot = await getDocs(q);
// If the doc is empty, write new data. Else, update it
if (querySnapshot.empty) {
    await addDoc(collection(firestore, "users"), {
        uid: user.uid,
        role: "Student",
        last_login: dt,
        fname: null,
        lname: null
    });
    // Go to profile.html
    goToUrl("profile.html");
} else {
    // There is only one document for the user
    const userDocRef = querySnapshot.docs[0].ref;
    await updateDoc(userDocRef, {
        last_login: dt
    });
    goToUrl("profile.html");
} 
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121