Skip to content
Advertisement

How to catch Firebase promise in React?

I have a simple function that checks if the user has Premium access or not:

export const checkPremium = async () =>{
  if (auth.currentUser) {
    const q = query(collection(db_firestore, 'users'));
    onSnapshot(q, (querySnapshot) => {
      querySnapshot.forEach((doc) => {
        if (doc.id === auth.currentUser.uid) {
          return doc.data().userSettings.hasPremium
        }
      });
    })
  }
  else{
    return false
  }
}

I tried to catch this in various ways, but no luck, it always returns an “undefined” object.

const getPremium = async => {
checkPremium.then((response) => console.log(response))
}

const getPremium = async => {
let hasPremium = await checkPremium()
}

let hasPremium = checkPremium()

What is the correct way to get the returned Boolean value?

Advertisement

Answer

onSnapshot is meant for listening to a collection continuously, getting repeatedly notified as its value changes. It does not create a promise, so the promise returned by getPremium is unrelated to the data you will eventually get in onSnapshot. If you just want to get the value once, you should use getDocs:

export const checkPremium = async () =>{
  if (auth.currentUser) {
    const q = query(collection(db_firestore, 'users'));
    const querySnapshot = await getDocs(q);
    const match = querySnapshot.docs.find(doc => doc.id === auth.currentUser.uid);
    if (match) {
      return doc.data().userSettings.hasPremium);
    } else {
      return false;
    }
  }
  else{
    return false
  }
}

Also, instead of getting all the users and then using client side code to find the one with the right id, you could just fetch that individual doc directly:

const ref = doc(db_firestore, 'users', auth.currentUser.uid)
const snapshot = await getDoc(ref);
const data = snapshot.data();
if (data) {
  return data.userSettings.hasPremium
} else {
  return false
}
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement