Get older snapshot for pagination when querying with limit(toLast:)

假装没事ソ 提交于 2021-01-29 06:01:37

问题


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

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!!


回答1:


Say you have 10 documents:

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

Your limitToLast(5) will retrieve:

[6,7,8,9,10]

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)

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:

  • 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.


来源:https://stackoverflow.com/questions/63552271/get-older-snapshot-for-pagination-when-querying-with-limittolast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!