Google Firestore - how to get document by multiple ids in one round trip?

前端 未结 11 1794
余生分开走
余生分开走 2020-11-21 22:49

I am wondering if it\'s possible to get multiple documents by list of ids in one round trip (network call) to the Firestore.

相关标签:
11条回答
  • 2020-11-21 23:18

    You could use a function like this:

    function getById (path, ids) {
      return firestore.getAll(
        [].concat(ids).map(id => firestore.doc(`${path}/${id}`))
      )
    }
    

    It can be called with a single ID:

    getById('collection', 'some_id')
    

    or an array of IDs:

    getById('collection', ['some_id', 'some_other_id'])
    
    0 讨论(0)
  • 2020-11-21 23:19

    No, right now there is no way to batch multiple read requests using the Cloud Firestore SDK and therefore no way to guarantee that you can read all of the data at once.

    However as Frank van Puffelen has said in the comments above this does not mean that fetching 3 documents will be 3x as slow as fetching one document. It is best to perform your own measurements before reaching a conclusion here.

    0 讨论(0)
  • 2020-11-21 23:24

    I hope this helps you, it works for me.

    getCartGoodsData(id) {
    
        const goodsIDs: string[] = [];
    
        return new Promise((resolve) => {
          this.fs.firestore.collection(`users/${id}/cart`).get()
            .then(querySnapshot => {
              querySnapshot.forEach(doc => {
                goodsIDs.push(doc.id);
              });
    
              const getDocs = goodsIDs.map((id: string) => {
                return this.fs.firestore.collection('goods').doc(id).get()
                  .then((docData) => {
                    return docData.data();
                  });
              });
    
              Promise.all(getDocs).then((goods: Goods[]) => {
                resolve(goods);
              });
            });
        });
      }
    
    0 讨论(0)
  • 2020-11-21 23:26

    If you are using flutter, you can do the following:

    Firestore.instance.collection('your collection name').where(FieldPath.documentId, whereIn:[list containing multiple document IDs]).getDocuments();
    

    This will return a Future containing List<DocumentSnapshot> which you can iterate as you feel fit.

    0 讨论(0)
  • 2020-11-21 23:30

    Surely the best way to do this is by implementing the actual query of Firestore in a Cloud Function? There would then only be a single round trip call from the client to Firebase, which seems to be what you're asking for.

    You really want to be keeping all of your data access logic like this server side anyway.

    Internally there will likely be the same number of calls to Firebase itself, but they would all be across Google's super-fast interconnects, rather than the external network, and combined with the pipelining which Frank van Puffelen has explained, you should get excellent performance from this approach.

    0 讨论(0)
  • 2020-11-21 23:32

    The best you can do is not use Promise.all as your client then must wait for .all the reads before proceeding.

    Iterate the reads and let them resolve independently. On the client side, this probably boils down to the UI having several progress loader images resolve to values independently. However, this is better than freezing the whole client until .all the reads resolve.

    Therefore, dump all the synchronous results to the view immediately, then let the asynchronous results come in as they resolve, individually. This may seem like petty distinction, but if your client has poor Internet connectivity (like I currently have at this coffee shop), freezing the whole client experience for several seconds will likely result in a 'this app sucks' experience.

    0 讨论(0)
提交回复
热议问题