Property 'id' does not exist on type 'QuerySnapshot<DocumentData>'

Viewed 541

I receive this error in the following code: Property 'id' does not exist on type 'QuerySnapshot'.

my code gives an error. I am trying to first query a list of users (that are in a collection) from Firestore than use the data to query from an other collection. It seems like I am making an error while updating the list which could be caused by a mistake in query part.

const dailyTaskFunction = functions.pubsub.schedule("0 0 * * *").timeZone("GMT +3").onRun(async () => { 
        
    const users = await db.collection("users").where("location", "==", "GMT+3").get();
    const taskPromises = users.docs.map((doc) => {
        return db
          .collection("tasks")
          .where("dailyTasks", "==", true)
          .where("completed", "==", true)
          .where("userID", "==", doc.get("userID"))
          .get();
    });
    const taskDocs = await Promise.all(taskPromises);
    const actionsPromises = taskDocs.map((snapshot) => {
        return db.collection("tasks").doc(snapshot.id).set({ completed: false }, { merge: true });
    });
    await Promise.all(actionsPromises);
    return null;
});
3 Answers

QuerySnapshot class, doesn't contain any id property. However, QueryDocumentSnapshot does. According to the docs, the id is of type string and provides the document's ID. This means that you need to loop through the snapshot object using forEach to get its children that are of type QueryDocumentSnapshot. Now, you can simply use the id property for each and every document and use it further in your referece.

You need to iterate over the query snapshots returned to your variable taskDocs, so you can get a QueryDocumentSnapshot for each item, then you can get the id.

const dailyTaskFunction = functions.pubsub
  .schedule('0 0 * * *')
  .timeZone('GMT +3')
  .onRun(async () => {
    const users = await db
      .collection('users')
      .where('location', '==', 'GMT+3')
      .get()
    const taskPromises = users.docs.map((doc) => {
      return db
        .collection('tasks')
        .where('dailyTasks', '==', true)
        .where('completed', '==', true)
        .where('userID', '==', doc.get('userID'))
        .get()
    })
    const taskDocs = await Promise.all(taskPromises)
    const actionsPromises = taskDocs.map((snapshots) => {
      return snapshots.docs.map((snapshot) => {
        return db
          .collection('tasks')
          .doc(snapshot.id)
          .set({ completed: false }, { merge: true })
      })
    })
    await Promise.all(actionsPromises)
    return null
  })

taskDocs is an array of QuerySnapshot. You need to run loop on each document in each QuerySnapshot inside them. Those DocumentSnapshots will have the document ID:

    const actionsPromises = []
    
    taskDocs.forEach((userTasksDocs) => {
      userTasksDocs.docs.forEach((taskDoc) => {
        actionsPromises.push(
          db
            .collection('tasks')
            .doc(taskDoc.id)
            .set({ completed: false }, { merge: true })
        );
      });
    });
Related