I have a database structure like this:
Posts(collection) -> userID (document) -> Subposts (subcollection) -> document[isVisible: true]
We have different userIDs which means that each userID has a subcollection of different posts.
I want to set up a cloud function which periodically (every 2 minutes) checks all the documents in all the sub collections (Subposts) and if the field isVisible is true, then changes it to false.
This is what I did:
exports.changeIsVisibleFieldAfterDay = functions.pubsub
.schedule("every 2 minutes").onRun((context) => {
db.collection("Posts/{uid}/Subposts").get().then((snapshot) => {
if (snapshot.data().isVisible == true) {
snapshot.forEach((doc) => doc.update({isVisible: false}));
}
});
});
I’ve set up the {uid} wildcard because I need to check in each document subcollection (Subposts).
This implementation doesn’t seem to work.
Advertisement
Answer
For firestore query you must provide valid documentID.
If you wish to check for all users subcollections, there are few other ways to get it done!
- Using collection query
- Query the
Postscollection > iterate over the users - Query
Subpostswith valid doc ID for each user > iterate over the subpost documents - Update the doc with
{isVisible: false}based on condition
- Using collectionGroup query
- Use collectionGroup query on
Subpostscollection. This will return all subPosts of each user - iterate over the document and update with
{isVisible: false}based on condition
In your iteration snippet, the collection query returns QuerySnapshot and in this the iteration should be on the field docs, like below
snap.docs.forEach((doc) => {
if (doc.data().isVisible == true) {
doc.update({ isVisible: false });
}
});
Note: I prefer to go with async/await with for..loop instead of .then(), as forEach won’t give expected result with their inner await calls.