Programing

Google Firestore-한 번의 왕복으로 여러 ID로 문서를 얻는 방법은 무엇입니까?

lottogame 2020. 12. 2. 07:44
반응형

Google Firestore-한 번의 왕복으로 여러 ID로 문서를 얻는 방법은 무엇입니까?


Firestore로 한 번의 왕복 (네트워크 호출)으로 ID 목록으로 여러 문서를 가져올 수 있는지 궁금합니다.


Node 내에있는 경우 :

https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701

/**
* 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])}`);
* });
*/

아니요, 현재 Cloud Firestore SDK를 사용하여 여러 읽기 요청을 일괄 처리 할 수있는 방법이 없으므로 모든 데이터를 한 번에 읽을 수 있다고 보장 할 방법이 없습니다.

그러나 Frank van Puffelen이 위의 주석에서 말했듯이 이것은 3 개의 문서를 가져 오는 것이 하나의 문서를 가져 오는 것보다 3 배 느리다는 것을 의미하지는 않습니다. 여기서 결론에 도달하기 전에 자체 측정을 ​​수행하는 것이 가장 좋습니다.


다음과 같은 함수를 사용할 수 있습니다.

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

단일 ID로 호출 할 수 있습니다.

getById('collection', 'some_id')

또는 ID 배열 :

getById('collection', ['some_id', 'some_other_id'])

이를 수행하는 가장 좋은 방법은 Cloud Function에서 Firestore의 실제 쿼리를 구현하는 것입니다. 그러면 클라이언트에서 Firebase로 단 한 번의 왕복 호출 만있을 것입니다.

어쨌든이 서버 측과 같은 모든 데이터 액세스 논리를 유지하고 싶습니다.

내부적으로는 Firebase 자체에 대해 동일한 수의 호출이있을 수 있지만 모두 외부 네트워크가 아닌 Google의 초고속 상호 연결을 통해 이루어지며 Frank van Puffelen이 설명한 파이프 라이닝과 결합되어 뛰어난 성능을 얻을 수 있습니다. 이 접근법.


실제로는 다음과 같이 firestore.getAll을 사용합니다.

async getUsers({userIds}) {
    const refs = userIds.map(id => this.firestore.doc(`users/${id}`))
    const users = await this.firestore.getAll(...refs)
    console.log(users.map(doc => doc.data()))
}

또는 약속 구문으로

getUsers({userIds}) {
    const refs = userIds.map(id => this.firestore.doc(`users/${id}`))
    this.firestore.getAll(...refs).then(users => console.log(users.map(doc => doc.data())))
}

Here's how you would do something like this in Kotlin with the Android SDK.
May not necessarily be in one round trip, but it does effectively group the result and avoid many nested callbacks.

val userIds = listOf("123", "456")
val userTasks = userIds.map { firestore.document("users/${it!!}").get() }

Tasks.whenAllSuccess<DocumentSnapshot>(userTasks).addOnSuccessListener { documentList ->
    //Do what you need to with the document list
}

Note that fetching specific documents is much better than fetching all documents and filtering the result. This is because Firestore charges you for the query result set.


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.


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.

참고URL : https://stackoverflow.com/questions/46721517/google-firestore-how-to-get-document-by-multiple-ids-in-one-round-trip

반응형