我正在使用Firestore为我的应用程序构建聊天功能。我使用limit(toLast:)
是因为我是根据时间戳提取的,这个方法会给我保存在数据库中的最新消息。但是,当我试图在加载旧消息之前获取快照/文档时,这会给我带来麻烦。这是我的代码:
fileprivate func paginateFetchMessages() {
var query: Query!
if let nextStartingSnap = self.lastDocumentSnapshot {
query = DBCall.fireRef.collection("friendMessages")
.document(currentUID)
.collection(friendUID)
.order(by: "timestamp").limit(toLast: 5).start(afterDocument: nextStartingSnap)
} else {
query = DBCall.fireRef.collection("friendMessages")
.document(currentUID)
.collection(friendUID)
.order(by: "timestamp").limit(toLast: 5)
}
query.addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: (error!)")
return
}
guard let lastSnap = snapshot.documents.last else {
self.refreshControl.endRefreshing()
return
}
print(snapshot.documents)
self.lastDocumentSnapshot = lastSnap
snapshot.documentChanges.forEach({ (change) in
if change.type == .added {
let data = change.document.data()
let text = data["message"] as! String
let fromID = data["fromID"] as! String
let messageID = data["messageId"] as? String ?? ""
let isRead = data["isRead"] as? Bool ?? false
let timestamp = data["timestamp"] as! Timestamp
let user = MessageKitUser(senderId: fromID, displayName: "")
let message = MessageKitText(text: text, user: user, messageId: messageID, date: Date(), isRead: isRead, firDate: timestamp )
self.insertMessage(message)
self.refreshControl.endRefreshing()
}
})
}
}
当我使用CCD_ 2时,没有任何返回;最后一个";文件。每次分页时,我都需要在最后一个快照之前获得5个快照。
如果这没有意义,并且您有问题,请告诉我。非常感谢。
假设您有10个文档:
[1,2,3,4,5,6,7,8,9,10]
您的limitToLast(5)
将检索:
[6,7,8,9,10]
由于您使用的是start(afterDocument:
,Firestore在文档6
之后启动,这不是您想要的。相反,您希望转到end(beforeDocument:
:
query = DBCall.fireRef.collection("friendMessages")
.document(currentUID)
.collection(friendUID)
.order(by: "timestamp")
.end(beforeDocument: nextStartingSnap)
.limit(toLast: 5)
我还反转了CCD_ 7和CCD_。它对结果没有影响,但对我来说读起来稍微容易一些,因为它几乎是Firestore处理查询的方式:
- 它在
timestamp
上加载索引 - 它切断了
nextStartingSnap
以后的一切 - 然后返回结果中剩下的最后5个文档