Google Firestore - how to get document by multiple

2018-12-31 10:21发布

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

7条回答
荒废的爱情
2楼-- · 2018-12-31 10:39

You could use a function like this:

function getById (path, id) {
  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'])
查看更多
妖精总统
3楼-- · 2018-12-31 10:40

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.

查看更多
梦醉为红颜
4楼-- · 2018-12-31 10:40

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.

查看更多
春风洒进眼中
5楼-- · 2018-12-31 10:43

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.

查看更多
美炸的是我
6楼-- · 2018-12-31 10:46

if you're within Node:

https://github.com/googleapis/nodejs-firestore/blob/master/src/index.js#L533

/**
* Retrieves multiple documents from Firestore.
*
* @param {...DocumentReference} documents - The document references
* to receive.
* @returns {Promise<Array.<DocumentSnapshot>>} A Promise that
* contains an array with the resulting document snapshots.
*
* @example
* let documentRef1 = firestore.doc('col/doc1');
* let documentRef2 = firestore.doc('col/doc2');
*
* firestore.getAll(documentRef1, documentRef2).then(docs => {
*   console.log(`First document: ${JSON.stringify(docs[0])}`);
*   console.log(`Second document: ${JSON.stringify(docs[1])}`);
* });
*/
查看更多
妖精总统
7楼-- · 2018-12-31 10:50

This doesn't seem to be possible in Firestore at the moment. I don't understand why Alexander's answer is accepted, the solution he proposes just returns all the documents in the "users" collection.

Depending on what you need to do, you should look into duplicating the relevant data you need to display and only request a full document when needed.

查看更多
登录 后发表回答