使用limit(toLast :)查询时获取旧快照以进行分页 [英] Get older snapshot for pagination when querying with limit(toLast:)

查看:54
本文介绍了使用limit(toLast :)查询时获取旧快照以进行分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firestore为我的应用程序构建聊天功能.我使用的是 limit(toLast:),因为我是根据时间戳进行提取的,因此该方法为我提供了保存在数据库中的最新消息.但是,在尝试加载快照/文档以加载较旧的消息之前,这给我带来了麻烦.这是我的代码:

Im building a chat feature for my app using Firestore. I'm using limit(toLast:) because I'm fetching based on the timestamp, this method gives me the latest messages saved in my DB. But it is giving me trouble when trying to fetch the snapshot/documents prior to that for loading older messages. Heres my code:

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

当我使用 snapshot.documents.last 时,没有任何返回,因为我正在获取"last"消息.最初的文件.分页时,每次都需要在上一张之前获得5张快照.

When I use snapshot.documents.last nothing returns because im fetching the "last" documents initially. I need to get the 5 snapshots before the last, each time when paginating.

让我知道这是否没有道理,您有疑问.谢谢!!

Let me know if this doesn't make sense and you have questions. Thank you!!

推荐答案

假设您有10个文档:

[1,2,3,4,5,6,7,8,9,10]

您的 limitToLast(5)将检索:

[6,7,8,9,10]

由于您使用的是 start(afterDocument:,因此Firestore在文档 6 之后启动,这不是您想要的,而是您想 end(beforeDocument::

Since you're using start(afterDocument:, Firestore starts after document 6, which is not what you want. Instead you want to to end(beforeDocument::

query = DBCall.fireRef.collection("friendMessages")
.document(currentUID)
.collection(friendUID)
.order(by: "timestamp")
.end(beforeDocument: nextStartingSnap)
.limit(toLast: 5)

我也将 limit(toLast: end(beforeDocument:Firestore如何处理您的查询:

I also reverse the limit(toLast: and end(beforeDocument:. It makes no difference to the results, but reads slightly easier to me - as it's pretty much how Firestore processes your query:

  • 它在 timestamp 上加载索引.
  • 它切断了 nextStartingSnap 以后的所有内容.
  • 然后返回结果中剩余的最后5个文档.
  • It loads the index on timestamp.
  • It cut off everything from nextStartingSnap onwards.
  • It then returns the last 5 documents that remain in the result.

这篇关于使用limit(toLast :)查询时获取旧快照以进行分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆