Query with reference in firestore

Viewed 153

I am trying to find all documents with a specific reference field in a collection in firestore. I have seen a handful of articles about this, but none of them seem to work. I hope someone could tell me what I am doing wrong. This is the first code snippet I tried

const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);
    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`).where("childOrgReference", '==', childOrgReference).get()
        .then(function(querySnapshot) {
          querySnapshot.forEach(function(docu) {
            db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id).update({
              "isDeleted": true,
            });
          });
        });

The problem is no document gets found, I tested that by logging the id. The childOrgReference should be correct. I also tried another bit of code:

// const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);
    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`).where("childOrgReference.id", '==', context.params.childOrgId).get()
        .then(function(querySnapshot) {
          querySnapshot.forEach(function(docu) {
            db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id).update({
              "isDeleted": true,
            });
          });
        });

Does anyone have any idea what I am doing wrong?


Edit: this is the current code I have:

const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);
    logger.log(childOrgReference);

    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`)
        .where("childOrgReference", '==', childOrgReference)
        .get()
        .then(function(querySnapshot) {
          const updates = [];
          querySnapshot.forEach(function(docu) {
            logger.log(docu.id);
            const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id);
            updates.push(docuRef.update({"isDeleted": true}));
          });

          Promise.all(updates).then(() => {
            console.log("Documents Updated");
          }).catch((e) => console.log(e));
        });

Logging the reference logs the following:

DocumentReference {
  _firestore: Firestore {
    _settings: {
      projectId: 'fmis-online-dev',
      firebaseVersion: '9.6.0',
      libName: 'gccl',
      libVersion: '4.9.9 fire/9.6.0',
      ignoreUndefinedProperties: true
    },
    _settingsFrozen: true,
    _serializer: Serializer {
      createReference: [Function],
      createInteger: [Function],
      allowUndefined: true
    },
    _projectId: 'fmis-online-dev',
    registeredListenersCount: 0,
    bulkWritersCount: 0,
    _backoffSettings: { initialDelayMs: 100, maxDelayMs: 60000, backoffFactor: 1.3 },
    _clientPool: ClientPool {
      concurrentOperationLimit: 100,
      maxIdleClients: 1,
      clientFactory: [Function],
      clientDestructor: [Function],
      activeClients: Map {},
      failedClients: Set {},
      terminated: false,
      terminateDeferred: [Deferred]
    }
  },
  _path: ResourcePath {
    segments: [
      'organisations',
      '3dkI69YGRE20AMn9oNGL',
      'childOrganisations',
      'bunEfTrEjtNxaBlpT2zk'
    ]
  },
  _converter: {
    toFirestore: [Function: toFirestore],
    fromFirestore: [Function: fromFirestore]
  }
} 

This is the reference as displayed in the firestore console: enter image description here

The issue is that the people document doesn't get found. The id doesn't get logged. I have no clue where it goes wrong, but I suspect the reference in the people document might be incorrect. However, I do not know what it should be.

2 Answers

You code seems correct and is working for me. However, you are not handling the promises. You should using promise chaining or async-await:

const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);

// Find all people with corresponding childOrgReference
db.collection(`organisations/${context.params.orgId}/people`)
  .where("childOrgReference", '==', childOrgReference)
  .get()
  .then(function (querySnapshot) {
    const updates = []
    querySnapshot.forEach(function (docu) {
      const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id) 
      updates.push(docuRef.update({"isDeleted": true});
    });
  
    Promise.all(updates).then(() => {
      console.log("Documents Updated")
    }).catch(e => console.log(e))
  });

You can also use Batched Writes instead of running multiple promises.

const updatesBatch = db.batch()
querySnapshot.forEach(function (docu) {
      const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id) 
      updatesBatch.update(docuRef, {"isDeleted": true});
    });
})
updatesBatch.commit().then(() => console.log("Updated"))

If no documents are matching your query then there maybe any mismatch in reference you are looking for.

So as stated by @Dharmaraj the childOrgReference in the people document was incorrect. I fixed this by querying not on the full path, but just on the subcollection. So the working code I have is this:

const childOrgReference = db.collection(`childOrganisations`).doc(context.params.childOrgId);
    logger.log(childOrgReference);

    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`)
        .where("childOrgReference", '==', childOrgReference)
        .get()
        .then(function(querySnapshot) {
          const updates = [];
          querySnapshot.forEach(function(docu) {
            logger.log(docu.id);
            const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id);
            updates.push(docuRef.update({"isDeleted": true}));
          });

          Promise.all(updates).then(() => {
            console.log("Documents Updated");
          }).catch((e) => console.log(e));
        });
Related