Firestore 抛出“onSnapshot() 需要 1 到 4 个参数”

Posted

技术标签:

【中文标题】Firestore 抛出“onSnapshot() 需要 1 到 4 个参数”【英文标题】:Firestore throws 'onSnapshot() requires between 1 and 4 arguments' 【发布时间】:2020-01-14 02:43:20 【问题描述】:

我正在尝试从 firebase 获取所有当前用户未读消息。问题是我的onSnapshot() 返回以下错误,但它在初始加载时返回我所需的值。如果添加了新文档,则 onSnapshot() 不会因为该错误而再次触发

FirebaseError:函数 Query.onSnapshot() 需要 1 到 4 参数,但使用 0 个参数调用。

这是接收所有当前用户未读消息的辅助函数。

async getUnseenMessagesCount() 
    const collectionRef = (await firestore()).collection(this.collectionPath) //chats/$user_id+second_identifier/messages
    let allMessagesCount = 0
    let currentUserReadMessagesCount = 0
    try 
      collectionRef.onSnapshot().then(snapshot => 
        allMessagesCount = snapshot.docs.length
      )
      collectionRef
        .where('seenBy', '==', '') // compare against empty string because seenBy is userId.
        .onSnapshot()
        .then(snapshot => 
          currentUserReadMessagesCount = snapshot.docs.length
        )
     catch (error) 
      console.log(error)
    

    console.log(allMessagesCount)
    console.log(currentUserReadMessagesCount)
    console.log(allMessagesCount - currentUserReadMessagesCount)
  

由于我想从用户参与的所有聊天中获取所有未读消息计数,我在我的 vuex 操作中执行以下操作,该操作会在身份验证状态更改时激活:

new UserChatsDB(newUser.id).readAll().then(snapshot =>  //users/id/chats/chat_id: user_id+second_identifier
        if (snapshot.length > 0) 
          snapshot.forEach(element => 
            console.log(element)
            const count = new MessagesDB(
              element.chat_id
            ).getUnseenMessagesCount()
            console.log(count) //Returns pending Promise
          )
        
      )

什么会导致上述错误?有更好的方法吗?让我知道是否需要数据库结构。非常感谢任何帮助!

【问题讨论】:

您忘记了return 声明吗? @ConstantinBeer 你认为return 声明应该在哪里? 由于您想获取未读消息,我将其放在第二个collectionRef 之前,您正在查询未读文档。但不确定这是否能解决问题。 @ConstantinBeer 我确实尝试过,遗憾的是它并没有改变任何东西。 您是否也在currentUserReadMessagesCount = snapshot.docs.length这一行添加了return 【参考方案1】:

根据firebase的docs,你必须像这样使用onSnapshot()函数:

async getUnseenMessagesCount() 
    const collectionRef = (await firestore()).collection(this.collectionPath) //chats/$user_id+second_identifier/messages
    let allMessagesCount = 0
    let currentUserReadMessagesCount = 0
    try 
      collectionRef.onSnapshot(snapshot => 
        allMessagesCount = snapshot.docs.length
      )
      collectionRef
        .where('seenBy', '==', '') // compare against empty string because seenBy is userId.
        .onSnapshot(snapshot => 
          currentUserReadMessagesCount = snapshot.docs.length
        )
     catch (error) 
      console.log(error)
    

    console.log(allMessagesCount)
    console.log(currentUserReadMessagesCount)
    console.log(allMessagesCount - currentUserReadMessagesCount)
  

所以你必须删除你的then()

【讨论】:

以上是关于Firestore 抛出“onSnapshot() 需要 1 到 4 个参数”的主要内容,如果未能解决你的问题,请参考以下文章

哪个反应钩子与firestore onsnapshot一起使用?

如何通过 redux-observable/rxjs 使用 Firestore 实时更新(onSnapshot)?

Cloud Firestore 中 get() 和 onSnapshot() 的区别

将firestore onSnapShot与react redux一起使用的正确方法

firestore onSnapshot 更新值,但不更新 VueJS 中的 DOM

React:如何通过 Firestore onSnapshot 和 useEffect 使用最新状态?