12

I successfully check user's authentication state with onAuthStateChange observer and redirect user to the Dashboard page (react-native project). However, on the dashboard I already want to show some user specific data, e.g. enrolled programs/statistics. For that I need currentUser object to be initialised and populated, which takes some time (I need uid from there to get some data from Database). Thus, i'm looking for some way to wait until this process finishes successfully. What I'm trying to do it to use async/await syntax in componentDidMount, but the result returned is null. (Same syntax successfully works in other screens, but fails in the first one)

async componentDidMount() {
  try {
    let uid = await firebase.auth().currentUser.uid;
    console.log(uid);
  } catch(error) {
    console.log(error);
  }
}

What could be the best way to wait for currentUser object being loaded using async/await syntax? I believe that the reason could be that firebase returns null as the first result and then correct uid as the second one.

For now for the workaround, I'm using simple setInterval function, but I do not want to increase amount of loading time that much.

  let waitForCurrentUser = setInterval(() => {
    if ( firebase.auth().currentUser.uid !== null ) {
        clearInterval(waitForCurrentUser);
        let uid = firebase.auth().currentUser.uid;
        this.setState({uid});
        return firebase.auth().currentUser.uid;
    } else {
      console.log('Wait for it');
    }
  }, 700);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Denis
  • 175
  • 1
  • 1
  • 7

4 Answers4

0

The equivalence of setInterval is :

//calling the asynchronous function
  waitForCurrentUser(function(uid){
   if(uid)
   console.log('the user id is',uid)
  })

   async waitForCurrentUser(userIdIs){

    try {
       let uid = await firebase.auth().currentUser.uid;
       if(uid)
       {
         clearInterval(waitForCurrentUser);        
         this.setState({uid});
         userIdIs(uid); 
       }
       else {
       console.log('Wait for it');
      }

    }

    catch(e){
     console.log(e)
    }

  //  return userIdIs(uid);//returns promise
  };

Cheers :)

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
Codesingh
  • 3,316
  • 1
  • 11
  • 18
  • Unfortunately, it does not change much. It returns currentUser.uid as null or throws error, because this object has not finished loading or the first result is null and I need second one or something like that. So, I'm not sure how could I wait for this object to finish loading. – Denis May 06 '17 at 20:28
  • I think the control bypasses these statements... so it may work inside if condition.. – Codesingh May 07 '17 at 04:01
  • Where do you define userIdIs(uid)? Probably, it does not work in my case, because I have replaced it with return uid – Denis May 07 '17 at 07:48
  • please see the edits, i think this would surely work for you. – Codesingh May 07 '17 at 07:56
  • Still throws an error. I have put this.waitForCurrentUser((uid) => { console.log('the user id is',uid) }) in componentDidMount() section and pasted the function itself below, but it didn't help – Denis May 07 '17 at 09:08
  • I have set it to log currentUser instead of its uid, now it indicates user as null, logs ('wait for it') and stops. By the way, thanks a lot for your help and patience, I really appreciate it – Denis May 07 '17 at 09:19
0
export async function getAuthUserID(): Promise<string | undefined> {
  return await new Promise( (resolve, reject) => {
    firebase.auth().onIdTokenChanged(async (user) => {
      if (!user) {
        resolve(undefined);
      } else {
        resolve(user.uid);
      }
})
  }).then((uid: string | undefined)=>uid).catch(function(e) {
    throw (e);
  });
}
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 22 '22 at 00:44
0
// sleep function
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getCurrentUser() {
  while (!auth.currentUser)
    await sleep(100);
  return auth.currentUser;
}

getCurrentUser().then(console.log)

Explanation: wait until the currentUser attr is no longer "null" before returning it using the while loop and sleep function.

zChris128
  • 25
  • 6
-2
async getUid() {
        let user = await firebaseApp.auth().currentUser;
        let email = await user.uid;
}

Hope it's usefull for you