javascriptfirebasevue.jsfirebase-authenticationvuex

Attempting to make firebase.auth().currentUser a promise


When a user logs in, I'm trying to send them to a restricted page. So I'm protecting the route by checking for the user object. The problem is that when a user is created or logging in, the auth doesn't immediately change, so after creating or logging in, firebase.auth().currentUser can return null for a couple of milliseconds. So if I send them to the page, it will return an error.

This is what I'm trying to do in an attempt for the route to wait a while to see if the auth changes. I'm wondering if there is any issues with the code or a better way to write this.

P.S. I know that I can check for firebase.auth().onAuthStateChanged, but I don't understand how I can use it upon user creation or log in. It just runs in the background and I can't just send users a route when auth changes with no context. It also doesn't have a timeout.

getUser( { commit } ) {
  return new Promise( ( resolve, reject )=> {
    let user, i = 0
    function checkForUser() {
      setTimeout( ()=> {
        i++
        user = firebase.auth().currentUser
        if ( user ) {
          router.push( { path: '/restricted' } )
          resolve()
        } else if ( i > 30 ) {
          reject( { message: 'Something went wrong, please try again.' } )
        } else {
          checkForUser()
        }
      }, 100 )
   }  
   checkForUser()
  } )
},

Solution

  • In 2024 you can use authStateReady() https://firebase.google.com/docs/reference/js/auth.auth.md#authauthstateready

    async function getUser() {
      const auth = getAuth();
      await auth.authStateReady();
      return auth.currentUser;
    }
    
    getUser().then(user => {
      console.log('user: ', user);
    });