john
john

Reputation: 1998

how to query a firestore collection from latest to the oldest when using pagination?

I'm querying a firestore collection and uses flutterfire's FirestoreQueryBuilder for pagination and it should query 10 documents per page at a time.

Here is my firestore collection :

enter image description here

What I need is to query from the latest data to the oldest The latest is at the bottom and the oldest is at the top.

The problem is querying firestore collection always starts from the top. even though you will order the query by date like so: query.where(something).orderBy('date', descending: true). What this does is grab the first 10 documents from the top then order them by date which is not what i want.

So the question is how can we query firestore collection that starts from the bottom up so that i could get the first latest 10 documents?

Or another thing i'm thinking is can we reverse the order of firestore collection? That if we add a document, it should append to the top not push to the bottom? is this possible?

Here is my code for querying firestore collection:

  Query<T> collectionQuery<T>({
    required String path,
    required T Function(DocumentSnapshot<Map<String, dynamic>> snapshot,
            SnapshotOptions? options)
        fromMap,
    required Map<String, Object?> Function(T, SetOptions? options) toMap,
    Query<T> Function(Query<T>? query)? queryBuilder,
  }) {
    Query<T> query = firestore
        .collection(path)
        .withConverter<T>(fromFirestore: fromMap, toFirestore: toMap);
    if (queryBuilder != null) {
      return query = queryBuilder(query);
    } else {
      return query;
    }
  }

And here is how i use FirestoreQueryBuilder to display the collection:

  return FirestoreQueryBuilder<T>(
      pageSize: pageSize,
      query: query,
      builder: (context, snapshot, ___) {
        if (snapshot.isFetching) {
          return loading ?? const Center(child: CircularProgressIndicator());
        }
        if (snapshot.hasError) {
          return Center(
            child: Text(
              snapshot.error.toString(),
              style: Styles.k16Bold,
            ),
          );
        }
        if (snapshot.docs.isEmpty) {
          return emptyWidget ??
              const Center(
                  child: Text(
                'No item found',
                style: Styles.k18Grey,
              ));
        }
        return ListView.separated(
          padding: padding ?? const EdgeInsets.all(0),
          physics: const BouncingScrollPhysics(),
          shrinkWrap: true,
          controller: listController,
          reverse: reverListView,
          itemCount: snapshot.docs.length,
          separatorBuilder: (_, __) => separator,
          itemBuilder: ((context, index) {
            if (snapshot.hasMore && index + 1 == snapshot.docs.length) {
              // Tell FirestoreQueryBuilder to try to obtain more items.
              // It is safe to call this function from within the build method.
              if (connection) {
                snapshot.fetchMore();
              }
            }

            final list =
                reverseItems ? snapshot.docs.reversed.toList() : snapshot.docs;
            print('list: ${list.length}');

            if (sort != null) {
              final item = list[index].data();
              list.sort(sort);

              return itemBuilder(item, index);
            } else {
              final item = list[index].data();
              return itemBuilder(item, index);
            }
          }),
        );
      },
    );

Upvotes: 0

Views: 165

Answers (1)

Rohit Kharche
Rohit Kharche

Reputation: 2919

try something like

final query = FirebaseFirestore.instance.collection('users')
                  .orderBy("timestamp")
                  .limit(10);

This will give you the result where the latest data will be at the bottom and the oldest will at the top.

Upvotes: 2

Related Questions