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

Oot*_*oto 5 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())
            }
        })
    })

}
Run Code Online (Sandbox Code Playgroud)

这种方式看起来很有效,因为这种方式只获取集合中的最新消息。然而我发现这种方式有问题。当用户刷新页面时,用户无法获取过去的消息。

所以我就这样改了。

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

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

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

我认为如果我先获取所有当前消息并为新消息设置侦听器,但在我进入页面后立即触发侦听器,即使集合中没有更改并读取最新消息两次,它也是有效的。

Oot*_*oto 2

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

// 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
      })
  })

Run Code Online (Sandbox Code Playgroud)