Home > database >  Swift Firestore pagination is retrieving the next batch of documents but replacing the first batch
Swift Firestore pagination is retrieving the next batch of documents but replacing the first batch

Time:09-23

In Swift I'm trying to implement pagination and I'm able to retrieve the next batch of documents, but, instead loading them at the bottom of the UITableView, it's replacing the first batch. I'm not sure what I'm doing wrong. Any help is greatly appreciated. Here is my code:

private var currentKey: String?

func fetchGlimpseData() {
    if currentKey == nil {
        GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).limit(to: 3)
            .getDocuments { (snapshot, error) in
            
            guard let last = snapshot?.documents.last else { return }
            guard let allObjects = snapshot?.documents else { return }
            
            allObjects.forEach( { document in
                self.glimpse.removeAll()
                self.glimpse = Glimpse.parseData(snapshot: snapshot)
                self.glimpseTableView.reloadData()
            })
            self.currentKey = last.documentID
        }
    } else if currentKey != nil {
        GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).limit(to: 3).getDocuments { (snapshot, error) in
            
            guard let lastDoc = snapshot?.documents.last else { return }
            
            if snapshot?.isEmpty == false {
                GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).start(afterDocument: lastDoc).getDocuments { ( snapshot, error) in
                    guard let snap = snapshot?.documents else { return }
                    snap.forEach( { document in
                        self.glimpse = Glimpse.parseData(snapshot: snapshot)
                    })
                }
            }
            self.glimpseTableView.reloadData()
        }
    }
}


func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    let currentOffset = scrollView.contentOffset.y
    let maxOffset = scrollView.contentSize.height - scrollView.frame.size.height
    
    if maxOffset - currentOffset <= 40 {
        fetchGlimpseData()
    }
}

CodePudding user response:

I think the problem comes from the call to self.glimpse.removeAll() here:

GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).limit(to: 3)
    .getDocuments { (snapshot, error) in
    
    guard let last = snapshot?.documents.last else { return }
    guard let allObjects = snapshot?.documents else { return }
    
    allObjects.forEach( { document in
        self.glimpse.removeAll()
        self.glimpse = Glimpse.parseData(snapshot: snapshot)
        ...

Since you first remove all data from self.glimpse, the previous page of data is removed after you add the new one.

To keep both pages, don't call self.glimpse.removeAll().


As you pointed out in the comments, your second page is loaded by the else block - so the above can't cause that problem.

In the else block you also replace the existing value of self.glimpse with each snapshot though in this line:

self.glimpse = Glimpse.parseData(snapshot: snapshot)

So: whatever value self.glimpse had before that line, it'll be gone after the line has run.

I'd expect to see something where you add the Glimpse.parseData(snapshot: snapshot) to self.glimpse instead of replacing it each time.

  • Related