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
You can get the data of your document through
doc.data()
and from there checking ifredemptions.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.The problem is that you have two meanings for
doc
in your code:doc
is a function that you import from the Firestore SDK.doc
in the callback heresnapshot.forEach((doc) => {
. So nowdoc
isWhen you call
doc(FIREBASE_FIRESTORE, "users", uid, "redemptions", doc.id)
inside the callback,doc
refers to thatDocumentSnapshot
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:
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