0
//initialize auth change listener
useEffect(() => {
    auth.onAuthStateChanged((user) => {
        if (user) {
            router.replace('/')
        }
    })
    setInitializing(false)
}, [])

//*handled by login button
const login = async (e: any) => {
    e.preventDefault()

    if (!form.email || !form.password) {
        setError('Email Id and Password not found')
        return
    }
    try {
        await signInWithEmailAndPassword(auth, form.email, form.password)
        const idToken = await getIdToken()

        //if userId and password is wrong
        //return with an error
        if (!idToken) {
            setError('Invalid User')
            await signOut(auth)
            return
        }

        //retrieve user data from firestore
        const _getUser = await getUser(idToken!)

        //if no user found
        //return with an error
        if (_getUser.error) {
            alert(_getUser.error)
            setError(_getUser.error)
            await signOut(auth)
            return
        }

        //if user is found
        //store jwt token in cookie
        document.cookie = `{"jwt":${_getUser.jwt}}`
    } catch (e: any) {
        // console.log(e.message);
    }
}

Explaination-> useEffect initialized onAuthStateChanged listener and if user is found then it should instantly redirect the user to '/' route

login function try to sign in using email id and password (using signInWithEmailAndPassword())

After handling some time-consuming tasks using await, set document.cookie = 'boo:foo' (last line in try block)

Question-> onAuthStateChanged should redirect the user to '/' route instantly after signInWithEmailAndPassword() is resolved with a user but it wait until the login function is run completely or document.cookie is set. Why?

framework using - NEXT JS

language - Typescript

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Chinmoy kr
  • 69
  • 5

1 Answers1

0

JavaScript (in this context) is inherently a single-threaded language, and it seems that it can't get to calling your onAuthStateChanged handler until after your login function is done with its synchronous work.

You could put the code you want to keep from blocking the handler in a block like this:

setTimeout(() => {
  // code that runs later goes here
}, 0);

A construct like this ensure that the event loop has a change to execute other code, before running the code inside this block.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807