Is there a method to iterate through all documents in a collection in firestore
Yes, you can simply query the collection for all its documents using the get() method on the collection reference. A CollectionReference object subclasses Query, so you can call Query methods on it. By itself, a collection reference is essentially an unfiltered query for all of its documents.
Android: Query.get()
iOS/Swift: Query.getDocuments()
JavaScript: Query.get()
In each platform, this method is asynchronous, so you'll have to deal with the callbacks correctly.
See also the product documentation for "Get all documents in a collection".
db.collection("cities").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
});
If you know that there aren't too many docs in the collection (e.g. thousands or millions) then you can just use collectionRef.get()
as described in the top-voted answer here and explained in Firebase docs.
However, in many cases, a collection can contain large numbers of documents that you can't just "get" at once, as your program's memory usage will explode. In these cases you need to implement a different traversal logic that will go through the entire collection by batches. You also need to ensure that you don’t miss any documents or process any of them multiple times.
This is why I wrote Firecode, an open-source Node.js library that solves precisely this problem. It is an extremely light, robust, well-typed, and well-documented library that provides you with configurable traverser objects that walk you through a given collection.
You can find the Github repo here and the docs site here. Also, here's a short snippet that shows you how you would traverse a users
collection with Firecode.
const usersCollection = firestore().collection('users');
const traverser = createTraverser(usersCollection);
const { batchCount, docCount } = await traverser.traverse(async (batchDocs, batchIndex) => {
const batchSize = batchDocs.length;
await Promise.all(
batchDocs.map(async (doc) => {
const { email, firstName } = doc.data();
await sendEmail({ to: email, content: `Hello ${firstName}!` });
})
);
console.log(`Batch ${batchIndex} done! We emailed ${batchSize} users in this batch.`);
});
console.log(`Traversal done! We emailed ${docCount} users in ${batchCount} batches!`);