0

I would like to make a query on a collection of documents, each document contain an id that is in an array. The query should be dynamic because the ids in the array change frequently. I've tried this but it doesn't work

const postsCol = await admin.firestore().collection('posts')
idsList.forEach(elem => {
  postsCol.where('sentBy', '==', elem)
})
postsCol.orderBy("sentAt", "desc").limit(5)
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
dhammani
  • 141
  • 1
  • 14
  • 1
    From what I understand you're trying to query Firestore to get the posts by a list of authors. This type of `OR` query is currently not possible with Firestore. See https://stackoverflow.com/questions/54987399/firestore-search-array-contains-for-multiple-values – Frank van Puffelen Jun 19 '19 at 11:18
  • @FrankvanPuffelen Hi Frank, what is your opinion on the below answer by Renaud? Would appreciate your thoughts on chaining queries like that. My use case is to have 1 - 5 (max 20) in a list, each returning 30 documents with 30 fields each. Is it scalable? – Wesley Barnes Feb 19 '21 at 20:54
  • On further research, I think the .where "in" is going to solve my problem as described here. Very useful feature. https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html – Wesley Barnes Feb 19 '21 at 21:08

1 Answers1

3

To query a Firestore collection, you need to use the get() method.

Doing const postsCol = await admin.firestore().collection('posts') will not query the database, it just defines a CollectionReference. The same for postsCol.where('sentBy', '==', elem) or postsCol.orderBy("sentAt", "desc").limit(5): they define a Query but do not fetch the database.

Each query to a collection with the get() method is an asynchronous operation: the get() method returns a Promise which resolves with the results of the query.

Since you want to trigger several queries in parallel, you should use Promise.all(), as follows:

const queries = [];

idsList.forEach(elem => {
   queries.push(admin.firestore().collection('posts').where('sentBy', '==', elem).get());
})

Promise.all(queries)
.then(results => {
  //Do whatever you want with the results array which is an array of QuerySnapshots
  //See https://firebase.google.com/docs/reference/js/firebase.firestore.QuerySnapshot.html
})

Note: if you use this code in a Cloud Function, don't forget to return the Promises returned by the asynchronous operations (including the promise returned by Promise.all()).

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121