Search code examples
node.jsfirebasegoogle-cloud-firestore

How can I fetch a set of documents whose ids match an array of ids in node.js using firebase?


I'm working with Firebase Firestore and I have the following code to fetch a set of "lines":

for (let i = 0; i < indexes.length; i++) {
    const doc = await lineCollection.doc(indexes[i]).get();
    lineData.push(doc.data());
}

This seems like a really inefficient way to fetch the lines, especially when indexes is large. I'm wondering if there's a way in Firebase to fetch a set of documents in a collection given an array of ids (which is what indexes is).

I tried the following and variants thereof:

const docs = await lineCollection.where('id', 'in', indexes).get();
const docs = await lineCollection.where(FieldPath.documentId(), 'in', indexes).get();

But none of these work.

I'm using firebase 9.16.0 and firebase-admin 11.5.0 in Node 18.19.0. Is there a way with these versions of firebase and Node to fetch a set of documents matching ids in a given array all in one call?


Solution

  • This query assumes that the documents have a field id with the value you want to filter on:

    lineCollection.where('id', 'in', indexes)
    

    But it seems that you actually want to filter on the document ID, not a custom id field. To filter on document ID, you can use:

    lineCollection.where('__name__', 'in', indexes)
    

    Or without the magic string using FieldPath.documentId():

    lineCollection.where(FieldPath.documentId(), 'in', indexes)
    

    Your data structure looks pretty unusual for a NoSQL database. More common would be to include the order lines in the order document and manipulate them in one go.

    If you're new to modeling data in a NoSQL database, I recommend reading NoSQL data modeling techniques and watching Get to know Cloud Firestore.

    If you maintain your current structure, I recommend including the order ID in each line document, so that you can get all lines for an order with:

    lineCollection.where('orderId', 'in', 'ID of the order you are loading')