Brendon Cheung
Brendon Cheung

Reputation: 1035

Flutter firestore pagination doesn't start after a document,

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,

Upvotes: 1

Views: 556

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83068

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.

Upvotes: 1

Related Questions