Flutter | Cloud Firestore Snapshot Pagination

Flutter | Cloud Firestore Snapshot Pagination

TB

Teqani Blogs

Writer at Teqani

August 12, 20253 min read

In this article, we delve into creating efficient pagination logic when listening to real-time data as a snapshot from Cloud Firestore. The goal is to listen to the last few data points in real-time and load older data using pagination logic. This approach optimizes resource usage and reduces costs by avoiding the need to listen to all data in real-time. Discover how to implement SnapshotPaginationController and SnapshotPaginationListView to manage your data effectively.



Introduction

Firestore's default snapshots() API is excellent for real-time data but lacks built-in pagination. Combining .startAfterDocument() with .limit() is complex, especially for clean state management. The solution is to utilize SnapshotPaginationController and SnapshotPaginationListView.



SnapshotPaginationController

The SnapshotPaginationController class provides the core functionality for handling pagination with Firestore snapshots. It manages the query, data transformation, page size, and loading states. The key components include:



  • query: The Firestore query to paginate.
  • fromDoc: A function to transform a DocumentSnapshot into a data model.
  • pageSize: The number of items to load per page.


How Each Method Works

The SnapshotPaginationController class uses several methods to handle pagination efficiently:



  • init(): Called once at startup. Loads the first page of data and starts listening for new messages via snapshots.
  • _loadInitial(): Pulls the first pageSize documents. Stores the last document for pagination and populates the _items list.
  • _listenNewData(): Subscribes to Firestore's snapshots(). When new data arrives, it replaces the top portion of _items without touching the older messages.
  • loadMore(): Triggered when scrolling to the top. Uses .startAfterDocument(_lastDoc) to get the next page. Appends results to _items. Stops when no more documents are left.
  • disposeController(): Cancels the Firestore subscription to avoid memory leaks.


Using with SnapshotPaginationListView

The SnapshotPaginationListView widget simplifies the integration of the SnapshotPaginationController into a Flutter UI. Key features include:



  • Takes a SnapshotPaginationController.
  • Renders controller.items.
  • Calls controller.loadMore() when the user scrolls near the top.
  • Optionally shows a loader widget during pagination.


How It Works

The SnapshotPaginationListView handles scrolling and loading behavior:



  1. Listening to Scroll: Attaches a ScrollController and checks if reverse = false → load more when near top. If reverse = true (chat style) → load more when near bottom.
  2. Preserving Scroll Position: Before loading more, it stores beforeLoadOffset. After inserting older messages, it jumps back so the view doesn’t “jump”. For reverse = true chat lists, Firestore data is prepended, but the UI order makes it look appended—so less adjustment is needed.
  3. Custom Loader: You can pass loadingIndicator to customize the “loading older messages” UI.
  4. Works with Any Type: The widget is generic <T> and uses itemBuilder for rendering.
TB

Teqani Blogs

Verified
Writer at Teqani

Senior Software Engineer with 10 years of experience

August 12, 2025
Teqani Certified

All blogs are certified by our company and reviewed by our specialists
Issue Number: #68eba90a-66b6-4cce-9d87-46ddd23ca5a8