Flutter firestore pagination doesn't start after a document,

263

I cannot test/try your code at this moment but I think this is because startAfter(lastPage["creationDate"]) is not correct.

You need to pass a list of values to startAfter() (a list with a unique item in your case). Since lastPage is a DocumentSnapshot you therefore need to use get() or data(), like startAfter([lastPage.get("creationDate")]).


Note that you could instead use the startAfterDocument() method to which you pass the DocumentSnapshot itself. It is somehow more adapted to your case, since you have only one sorting.

Share:
263
Brendon Cheung
Author by

Brendon Cheung

Updated on January 01, 2023

Comments

  • Brendon Cheung
    Brendon Cheung over 1 year

    I am trying to implement a pagination feature on my list and I've been following this official documentation https://firebase.google.com/docs/firestore/query-data/query-cursors

    Here is a main code:

      Future<List<Review>> fetchReviewPaginated(int limit) async {
        var ref = _firestore.collection('reviews').orderBy('creationDate', descending: true);
    
        if (_isFetchingUser) return null;
    
        _isFetchingUser = true;
    
        if (cachedReview == null) {
          var snapshot = await ref.limit(limit).get();
          lastPage = snapshot.docs.last;
          cachedReview = snapshot.docs.map((e) => Review.fromMap(e.data())).toList();
        } else {
          var snapshot = await ref.startAfter(lastPage["creationDate"]).limit(limit).get();
          lastPage = snapshot.docs.last;
          cachedReview.addAll(snapshot.docs.map((e) => Review.fromMap(e.data())).toList());
        }
        if (cachedReview.length < limit) hasNext = false;
    
        _isFetchingUser = false;
        notifyListeners();
        return cachedReview;
      }
    

    My widget will call fetchReviewPaginated(5) and display what is in cachedReviews. If the cachedReviews is null, then it will fetch 5 of reviews, then it will startAfter what is in the last of the cachedReviews and get another 5 documents after that point.

    Problem is that this function always returns the same 5 items and doesn't truly start after what I specify,

    • Brendon Cheung
      Brendon Cheung almost 3 years
      I've changed it to this var snapshot = await ref.startAfterDocument(lastPage).limit(limit).get(); and how it works! I tried this approach before and i didnt work before
    • Frank van Puffelen
      Frank van Puffelen almost 3 years
      Good to hear that works Brendon. 👍 When you have the full DocumentSnapshot available, it's always best to pass that to the pagination methods - as they can find both the timestamp (or whatever fields you ordered on) and the document ID from it, as needed.