Firestore:在聊天中列出消息的有效方法是什么?

时间:2019-11-19 00:58:22

标签: javascript firebase vue.js google-cloud-firestore

我正在尝试使用Firestore创建类似于应用的聊天,并尝试列出聊天中的所有消息并在每次添加消息时对其进行更新。

我首先尝试过这种方式来实现它。

mounted() {

    docRef.collection('messages').orderBy('timestamp', 'desc').limit(1).onSnapshot((querySnapShot) => {
        querySnapShot.forEach((doc) => {
            if (!doc.metadata.hasPendingWrites) {
                this.messages.push(doc.data())
            }
        })
    })

}

这种方式似乎很有效,因为这种方式只能获取集合中的最新消息。但是,我发现这种方式存在问题。用户刷新页面时,该用户无法获取过去的消息。

所以我这样改变了。

mounted() {
    docRef.collection('messages').orderBy('timestamp', 'asc').onSnapshot((querySnapShot) => {
        querySnapShot.docChanges().forEach((change) => {
            if (change.type === 'added') {
                 this.messages.push(change.doc.data())
              }
        })
    })
}

这种方式符合我的预期。但是这种方式需要很多请求,因为每次更改集合时,我都需要阅读集合中的所有文档。

在聊天中列出消息的有效方法是什么?

我认为,如果我先获取所有当前消息并为新消息设置侦听器,那是可行的,但是即使集合中没有任何更改并两次读取最新消息,进入页面后也会立即触发该侦听器。 / p>

2 个答案:

答案 0 :(得分:1)

我最终只是使用一个标志来检查初始触发器是否完成。我不知道这是不是很聪明的方法,但是可行。

// Get all current messages
  docRef.collection('messages').orderBy('timestamp', 'asc').get().then((querySnapShot) => {
    querySnapShot.forEach((doc) => {
      this.messages.push(doc.data())
    })
  })

// Update for new messages (Skip the initial loading)

  docRef.collection('messages').orderBy('timestamp', 'desc').limit(1).onSnapshot((querySnapShot) => {
      querySnapShot.forEach((doc) => {
        if (!doc.metadata.hasPendingWrites && this.isInitialDone) {
          this.messages.push(doc.data())
        }
        this.isInitialDone = true
      })
  })

答案 1 :(得分:0)

您将需要设置一个适当的限制,或者添加一个过滤器来确定所需的限制。

如果要限制大小,只需在第一个查询中将limit(1)更改为您想要的数字即可。

如果要使用过滤器,则可能应该使用已有的时间戳,以便确定过去的时间。

这是用于限制结果大小的两个选项。您可以将一个或两个一起使用,但是没有其他方法可以限制结果集的大小。