skip to Main Content

I have a collection of "Offers", that I query within Firestore. However, for each "Offer", returned, I’d like to see if the user has used it or not. This is stored in another collection:

const ref = doc(FIREBASE_FIRESTORE, "users", uid, "redemptions", doc.id);

if this document exists the user has used the offer and I should update the object with exists: true

I have tried to do this in the below code, however, I am getting;

[TypeError: doc is not a function (it is Object)]

CODE

export const getOffers = async (id, uid) => {
  const ref = collection(FIREBASE_FIRESTORE, "venues", id, "offers");
  const q = query(ref, where("active", "==", true));
  const snapshot = await getDocs(q);
  const data = [];
  snapshot.forEach((doc) => {
    const ref = doc(FIREBASE_FIRESTORE, "users", uid, "redemptions", doc.id);
    const redemptionSnapshot = getDoc(ref);
    data.push({
      id: doc.id,
      exists: redemptionSnapshot.exists(),
      ...doc.data(),
    });
  });
  return data;
};

I assume I cannot run another function within the forEach loop. So how would I do this?

2

Answers


  1. You can get the data of your document through doc.data() and from there checking if redemptions.length is greater than 0, or by checking its content.

    This is to say that you get all sub collections and documents through doc.data(), so doc.data().redemptions would be a valid selector.

    Login or Signup to reply.
  2. The problem is that you have two meanings for doc in your code:

    • At the top-level doc is a function that you import from the Firestore SDK.
    • But then you re-declare doc in the callback here snapshot.forEach((doc) => {. So now doc is DocumentSnapshot`.

    When you call doc(FIREBASE_FIRESTORE, "users", uid, "redemptions", doc.id) inside the callback, doc refers to that DocumentSnapshot and not to the global function anymore. And that’s why you get the error.

    To solve it, give the parameter in your callback a different name. For example:

    snapshot.forEach((docSnapshot) => {
      const ref = doc(FIREBASE_FIRESTORE, "users", uid, "redemptions", docSnapshot.id);
      const redemptionSnapshot = getDoc(ref);
      data.push({
        id: docSnapshot.id,
        exists: redemptionSnapshot.exists(),
        ...docSnapshot.data(),
      });
    });
    

    The error message you now get will disappear when you do this.


    You’ll get another problem though as getDoc is an asynchronous function and your code fails to handle that. For that I recommend checking out: Using async/await with a forEach loop

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search