javascript firebase“IN”限制为10的变通方案是否与onSnapshot兼容?

ffdz8vbo  于 2023-02-07  发布在  Java
关注(0)|答案(1)|浏览(161)

我遇到了firebase的“IN”限制10。虽然这里已经回答了一个变通方案:
Is there a workaround for the Firebase Query "IN" Limit to 10?
该线程中的所有解决方案似乎都不适用于侦听器“onSnapshot”。对于我的用例(Vue 3),我有一个可组合的/函数调用I,它查询在一个数组中传递的Firebase,该数组最多可以有100个文档ID值,并返回一个对象,如下所示。
这可能吗?

import { ref, watchEffect } from 'vue'
import { db } from '@/firebase/config'
import { collection, onSnapshot, query, where, documentId } from 'firebase/firestore'

const getUsersList = (idList) => { 
    // idList is an array of document ID's
    const documents = ref(null)
    let collectionRef = collection(db, 'users')
    collectionRef = query(collectionRef, where(documentId(), 'in', idList))
    // this fails if I pass in more than 10 elements in the array
    const unsub = onSnapshot(collectionRef, snapshot => {
        let results = []
        snapshot.docs.forEach(doc => {
            results.push({ ...doc.data(), id: doc.id })
        })
        // update values
        documents.value = results
    })
    watchEffect((onInvalidate) => {
        onInvalidate(() => unsub())
    })
    return { documents }
}

export default getCollectionRt
qacovj5a

qacovj5a1#

您必须初始化多个监听器,即相同数量的查询,但使用onSnapshot()(可能比为每个文档设置一个监听器更好)。

import { ref } from 'vue';
import { collection, query, where, documentId, onSnapshot } from 'firebase/firestore'

const users = ref({})
const dataLoaded = ref(false)

const addFirestoreListeners = async () => {
  const idList = [];

  for (let i = 0; i < idList.length; i += 10) {
    const items = idList.slice(i, i + 10)

    const q = query(collection(db, 'users'), where(documentId(), 'in', items))

    onSnapshot(q, (snapshot) => {
      if (dataLoaded.value) {
        snapshot.docChanges().forEach((change) => {
          if (change.type === 'added' || change.type === 'modified') {
            users.value[change.doc.id] = change.doc.data()
          } else (change.type === 'removed') {
            users.value[change.doc.id] = null
          }
        })
      } else {
        snapshot.forEach((doc) => {
          users.value[doc.id] = doc.data()
        })

        dataLoaded.value = true
      }
    })
  }
}

dataLoaded标志检查监听器是否第一次获取数据或接收到更新。我使用了一个Map,其中的键是文档ID,因此它可以很容易地删除,但请将其更改为数组或任何其他所需的结构。

相关问题