skip to Main Content

In firebase I have a bunch of documents I need to download them in batches of then from newest to oldest

I tried to order my documents by a timestamp in descending order and use startAfter(LastDocument)to paginate through the results.

The issue is that because I use startAfter(LastDocument) newly created documents aren’t shown because they are before the last document

this is my code:

    func queryCards() {
        let collectionReference = database.collection("posts")
        let query: Query
        if let lastDocument = lastDocumentToIgnore {
           query = collectionReference
                    .order(by: "timestamp", descending: true)
                    .start(afterDocument: lastDocument)
                    .limit(to: 5)
            } else {
                query = collectionReference
                    .order(by: "timestamp", descending: true)
                    .limit(to: 5)
            }
            
            query.getDocuments { (querySnapshot, error) in
                if let error = error {
                    print("Error retrieving documents: (error)")
                    return
                }
                
                // Process retrieved documents using the separate function
                self.processQuerySnapshot(querySnapshot)
            }
        }
    }

2

Answers


  1. Chosen as BEST ANSWER

    If anyone has the same issue, you need to also have a FirstDocument

    example implementation:

    func queryCards() {
        let collectionReference = database.collection("DocumentsToPaginate")
        let numberOfDocumentsToRetrieve = 3
        
        getFirstDocument() { [weak self] (firstDocumentStart, error) in
            guard let self = self else { return }
            
            if let error = error {
                print("Error fetching last document: (error)")
                return
            }
            let query: Query
            if let firstDocument = firstDocumentStart{
                query = collectionReference
                    .order(by: "timestamp", descending: false) // Replace with your actual timestamp field
                    .start(afterDocument: firstDocument)
                    .limit(to: numberOfDocumentsToRetrieve)
                
                query.getDocuments { (querySnapshot, error) in
                    if let error = error {
                        print("Error retrieving documents: (error)")
                        return
                    }
                    
                    // Process retrieved documents using the separate function
                    self.processQuerySnapshot(querySnapshot, isNew: true)
                }
            } 
        }
    
        getLastDocument() { [weak self] (lastDocumentToIgnore, error) in
            guard let self = self else { return }
            
            if let error = error {
                print("Error fetching last document: (error)")
                return
            }
            let query: Query
            if let lastDocument = lastDocumentToIgnore {
                query = collectionReference
                    .order(by: "timestamp", descending: true) // Replace with your actual timestamp field
                    .start(afterDocument: lastDocument)
                    .limit(to: numberOfDocumentsToRetrieve)
            } else {
                query = collectionReference
                    .order(by: "timestamp", descending: true) // Replace with your actual timestamp field
                    .limit(to: numberOfCardsToRetrieve)
            }
            
            query.getDocuments { (querySnapshot, error) in
                if let error = error {
                    print("Error retrieving documents: (error)")
                    return
                }
                
                // Process retrieved documents using the separate function
                self.processQuerySnapshot(querySnapshot, isNew: false)
            }
        }
    }
    

  2. If you show the documents in reverse chronological order, then it makes sense that subsequent pages show older documents – and thus do not show the newest additions. If you would show the newest documents on subsequent pages, that becomes wholly confusing for your users too.

    If you want to alert your user that there have been additions to the earlier pages that they don’t see, the common approach for that would be to:

    • Register a realtime listener for documents that were added/changed after the user saw the first page.
    • When a new document shows up in that listener, show a banner at the top of the list saying that there were new changes – and that they should scroll back to the top to see those.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search