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
Posts
collection > iterate over the users - Query
Subposts
with 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
Subposts
collection. 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.