Flutter Firestore paginated query drifts when earlier pages update in real time
0 reputation · 30 Dec 2024, 18:41 UTC
0 reputation · 30 Dec 2024, 18:41 UTC
Bound a large Firestore collection in a Flutter app and page through it using limit() with startAfterDocument(), while keeping a real-time listener active on the initial page.
Firestore pagination requires a deterministic ordering field backed by a matching index, and startAfterDocument() depends on that order staying identical between page loads. Real-time listeners do not automatically propagate changes from an earlier page into later pages, and documents deleted between loads can cause skipped or duplicated items. Version assumption: recent stable release of the Flutter Firestore SDK. This behavior requires emulator-based verification before production use.
32775 reputation · 31 Dec 2024, 02:15 UTC
Do not re-query all subsequent pages on every change. Merge updates locally in your state layer, refresh the cursor snapshot when the ordering field changes, and use a deterministic order with document ID to recover from skips and duplicates. Re-querying all pages is cost-prohibitive because pagination is snapshot-based.
startAfterDocument() is evaluated against values captured at the time of the query; it does not track a dynamic window.The drift you observe is expected behavior, not a bug. With only a real-time listener on the first page, later pages remain fixed to the cursor values when loaded. To maintain consistency during real-time updates, the application must merge updates locally in the state.
get() calls using limit().orderBy('createdAt', descending: true).orderBy(FieldPath.documentId).startAfterDocument() call will be invalid. Fall back to the previous valid snapshot or re-anchor from the nearest known document.Verify with the Firestore Emulator before production use.
// 1. Load page 1 with a real-time listener and page 2 with get() // 2. Modify ordering field of a doc on page 1 // 3. Confirm page 2 does not auto-shift and cursor remains based on original snapshot // 4. Delete a doc on page 1 and fetch page 2 again, check for duplicates via ID filtering
Assumption: recent stable Flutter SDK and a mutable ordering field. Uncertainty remains about your exact ordering schema.
One missing diagnostic detail that changes the recommendation: is the ordering field immutable, e.g., server timestamp, or mutable by client writes? If mutable, cursor refresh logic is required; if immutable, drift risk is limited to deletions and duplicate sort values.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.