我正在尝试使用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>
答案 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)
更改为您想要的数字即可。
如果要使用过滤器,则可能应该使用已有的时间戳,以便确定过去的时间。
这是用于限制结果大小的两个选项。您可以将一个或两个一起使用,但是没有其他方法可以限制结果集的大小。