首页 > 解决方案 > 遍历文档 uid 列表并在 Firestore 中创建侦听器

问题描述

在我的 Vuex 商店中,我有一个操作,它从当前用户的 Firestore UserDataCollection 文档中获取关注用户的 uid 列表,遍历它们,并为要在 UI 上显示的每个文档生成数据。使用 .get() 可以正常工作,但我正在尝试将其转换为 .onSnapshot(),以便获得实时更新。

我尝试使用 .onSnapshot() 完全不成功,因为我在网上或 Firebase 文档中找不到任何关于如何在通过 uid 数组映射后实现此功能的参考。

我尝试删除承诺,因为 onSnapshot 似乎不适用于承诺,并将 .get() 替换为 .onSnapshot(),但这不起作用。

有谁知道给定下面的代码来实现 Firestore .onSnapshot() 侦听器的正确方法?

getCircle({state, commit}) {
      const circle = state.userProfile.circle
      let promises = circle.map(u => userDataCollection.doc(u).get())
      
        return Promise.all(promises)

        .then(querySnapShot => {
          let circleData = []
          if (querySnapShot.empty) {
            console.log("empty")
          } else {
            querySnapShot.forEach(doc => {
              let item = doc.data()
              circleData.push(item)
             }
            )
          }
          commit('setUserCircle', circleData)
        })
   },

根据回复编辑

我在 forEach 中添加了 .onSnapshot,如下面的代码所示。在 vue devtools 中,它显示了我的 Vuex 存储中正确数量的数据条目,但是它们都是未定义的。

getCircle({state, commit}) {
  const circle = state.userProfile.circle
  let promises = circle.map(u => userDataCollection.doc(u).get())
  
    return Promise.all(promises)

    .then(querySnapShot => {
      let circleData = []
      if (querySnapShot.empty) {
        console.log("empty")
      } else {
        querySnapShot.forEach(x => {
          let itemId = x.data().uid
          userDataCollection.doc(itemId)
            .onSnapshot((doc) => {
              let item = doc.data()
              console.log(doc.data())
              circleData.push(item)
          })   
          }
        )
      }
      commit('setUserCircle', circleData)
    })

},

标签: javascriptfirebasevue.jsgoogle-cloud-firestorevuex

解决方案


呈现的代码在回调commit之前只运行一次。onSnapshot我尝试创建显示机制的示例(我假设circle数组已正确分配,并且我有 3 个项目硬编码):

let promises = circle.map(u => userDataCollection.doc(u).get())

Promise.all(promises)
.then( querySnapShot =>  {
    var circleData = []
     querySnapShot.forEach( x  => {
        let itemId = x.data().uid
        userDataCollection.doc(itemId).onSnapshot(doc => {
            let item = doc.data()
            circleData.push(item)
            console.log("inside snapshot: ",circleData.length)
        })
    })
    console.log("outside foreach: ",circleData.length)
})

如果您运行此代码,您应该在控制台中看到类似这样的内容(我已在节点中运行此代码):

outside foreach:  0
inside snapshot:  1
inside snapshot:  2
inside snapshot:  3

如果您在 Firestore 中进行任何更改,您将获得另一个控制台日志inside snapshot: 4

我对您的应用程序逻辑没有完全了解,但是我认为该commit语句应该在onSnapshot侦听器内部。但当然,根据我掌握的信息,这只是猜测。


推荐阅读