简体   繁体   中英

How do I fetch documents with specific ids (plural) from a firestore collection using the `in` clause?

I already read few post on the topic, but for some reason I can not fetch the docs which I need. I have a collection users with auto generated id and each doc contains name and email. Here is my collection: 在此处输入图像描述

Please note, the ids are auto generated.

Then, what I try to do in the code is the following:

firebase.firestore()
        .collection("users")
        .where(
          "id",
          "in",
          ids
        )
        .get()
        .then((querySnapshot) => {
            const people = [];
            querySnapshot.forEach(documentSnapshot => {
              people.push({
                  ...documentSnapshot.data(),
                  key: documentSnapshot.id
                  });
                });
              console.log("people: ", people);
          });

My people arrays is empty. I am pretty sure that my ids array has the correct ids. I am not sure if this part is correct:

firebase.firestore()
        .collection("users")
        .where(
          "id",
          "in",
          ids
        )
        .get()

Is "id" the correct name of the auto generated column?

To query a document by it's ID, you should make use of firebase.firestore.FieldPath.documentId() which returns a special value that can be used with the where() filter to search by a document's ID.


The following code has been tweaked from this documented gist (Typescript/JavaScript):

function chunkArr(arr, n) {
  if (n <= 0) throw new Error("n must be greater than 0");
  return Array
    .from({length: Math.ceil(arr.length/n)})
    .map((_, i) => arr.slice(n*i, n*(i+1)))
}

async function fetchDocumentsWithId(collectionQueryRef, arrayOfIds) {
  // in batches of 10, fetch the documents with the given ID from the collection
  const fetchDocsPromises = chunkArr(arrayOfIds, 10)
    .map((idsInChunk) => (
      collectionQueryRef
        .where(firebase.firestore.FieldPath.documentId(), "in", idsInChunk)
        .get()
    ))

  return Promise.all(fetchDocsPromises)
    .then((querySnapshotArray) => {
      const allDocumentsArray = [];
      for (let querySnapshot of querySnapshotArray) {
        querySnapshot.forEach(doc => allDocumentSnapshotsArray.push({...doc.data(), key: doc.id}))
      }
      return allDocumentsArray;
    });
}

const usersColRef = firebase.firestore()
        .collection("users");
const ids = [ /* ... */ ];

const docDataArray = fetchDocumentsWithId(usersColRef, ids);

If you were to use the unedited version of the gist , you would instead use:


const usersColRef = firebase.firestore()
        .collection("users");
const ids = [ /* ... */ ];
const docDataArray = [];

await fetchDocumentsWithId(usersColRef, ids, (doc) => docDataArray.push({ ...doc.data(), key: doc.id }))

console.log(docDataArray)

Note: I'd avoid using the term "key" for Firestore and instead use "id". If you are using "id" in your documents, you could always use "_id" instead.

In this situation I am assuming that ids is an array that you have in your client side code and are looking to query only for those ids in firestore?

Unfortunately, when using the .where() functionality in firestore, it does not query against the document ID's but rather the content of the document.

If you wanted to use the .where() indexing capability of firestore, you would need to add a uid field to the actual document data. Once you do that, you should be able to query for only the ID's you would like.

From the firestore docs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM