Bird
Raised Fist0
Firebasecloud~20 mins

Cursor-based pagination (startAfter, endBefore) in Firebase - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Firestore Cursor Pagination Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ service_behavior
intermediate
2:00remaining
Understanding startAfter behavior in Firestore queries

You have a Firestore collection of documents ordered by a timestamp field. You want to fetch the next page of 5 documents after a specific document snapshot using startAfter. What will be the result of the query?

Firebase
const query = firestore.collection('posts').orderBy('createdAt').startAfter(lastDoc).limit(5);
const snapshot = await query.get();
const results = snapshot.docs.map(doc => doc.data());
AThe query returns 5 documents strictly after the document represented by lastDoc, excluding lastDoc itself.
BThe query returns 5 documents including the document represented by lastDoc.
CThe query returns 5 documents before the document represented by lastDoc.
DThe query returns all documents in the collection ignoring lastDoc.
Attempts:
2 left
💡 Hint

Think about how startAfter works in Firestore pagination.

❓ service_behavior
intermediate
2:00remaining
Effect of endBefore in Firestore pagination

You want to fetch the previous page of 5 documents before a specific document snapshot using endBefore. What does the query return?

Firebase
const query = firestore.collection('posts').orderBy('createdAt').endBefore(firstDoc).limitToLast(5);
const snapshot = await query.get();
const results = snapshot.docs.map(doc => doc.data());
AThe query returns 5 documents strictly before the document represented by firstDoc, excluding firstDoc.
BThe query returns 5 documents including the document represented by firstDoc.
CThe query returns all documents in the collection ignoring firstDoc.
DThe query returns 5 documents after the document represented by firstDoc.
Attempts:
2 left
💡 Hint

Remember how endBefore works with limitToLast in Firestore.

❓ Architecture
advanced
3:00remaining
Designing efficient cursor-based pagination for large Firestore collections

You have a Firestore collection with millions of documents. You want to implement cursor-based pagination for a mobile app to load data efficiently. Which approach is best to minimize read costs and latency?

AFetch all documents at once and paginate on the client side to avoid multiple queries.
BUse <code>orderBy</code> on an indexed field and paginate with <code>startAfter</code> using document snapshots as cursors.
CUse <code>limit</code> without any cursor and fetch the first N documents repeatedly for each page.
DUse <code>orderBy</code> on a non-indexed field and paginate with <code>startAt</code> using field values as cursors.
Attempts:
2 left
💡 Hint

Think about Firestore indexing and how cursors work for efficient queries.

❓ security
advanced
3:00remaining
Securing Firestore cursor-based pagination queries

You want to ensure users can only paginate through documents they have access to in Firestore. Which security rule approach correctly enforces this during cursor-based pagination?

AUse client-side filtering after fetching all documents to enforce access control.
BWrite security rules that allow access to all documents in the collection during pagination to avoid errors.
CDisable security rules for pagination queries to improve performance.
DWrite security rules that check user permissions on each document individually, regardless of pagination cursors.
Attempts:
2 left
💡 Hint

Consider how Firestore security rules apply to queries and documents.

✅ Best Practice
expert
4:00remaining
Handling inconsistent data during Firestore cursor-based pagination

While paginating through a Firestore collection using startAfter, some documents are added or deleted concurrently. What is the best practice to ensure consistent pagination results?

AUse random ordering to distribute load and avoid conflicts.
BReload the entire collection on each page request to get the latest data.
CUse a stable, immutable field like a timestamp or unique ID for ordering and cursors to minimize inconsistencies.
DIgnore concurrent changes and rely on client-side merging of results.
Attempts:
2 left
💡 Hint

Think about how ordering fields affect pagination stability.

Practice

(1/5)
1. What does the startAfter method do in Firebase cursor-based pagination?
easy
A. It loads all documents from the beginning.
B. It ends the query before a specific document snapshot.
C. It deletes documents after a specific snapshot.
D. It starts loading documents after a specific document snapshot.

Solution

  1. Step 1: Understand the purpose of startAfter

    startAfter tells Firebase to begin loading documents after the given document snapshot, skipping that snapshot itself.
  2. Step 2: Compare with other cursor methods

    endBefore stops before a snapshot, but startAfter moves forward after it.
  3. Final Answer:

    It starts loading documents after a specific document snapshot. -> Option D
  4. Quick Check:

    startAfter = start after snapshot [OK]
Hint: Remember: startAfter skips the given document and moves forward [OK]
Common Mistakes:
  • Confusing startAfter with endBefore
  • Thinking startAfter includes the given document
  • Assuming startAfter loads all documents from start
2. Which of the following is the correct syntax to start a query after a document snapshot named lastDoc in Firebase?
easy
A. query.startAfter(lastDoc)
B. query.endAfter(lastDoc)
C. query.startBefore(lastDoc)
D. query.endBefore(lastDoc)

Solution

  1. Step 1: Recall Firebase query cursor methods

    The correct method to start after a document is startAfter().
  2. Step 2: Match method with snapshot variable

    Using startAfter(lastDoc) correctly applies the cursor after the lastDoc snapshot.
  3. Final Answer:

    query.startAfter(lastDoc) -> Option A
  4. Quick Check:

    Correct method is startAfter() [OK]
Hint: Use startAfter(snapshot) to move forward in pagination [OK]
Common Mistakes:
  • Using non-existent methods like endAfter or startBefore
  • Mixing up startAfter and endBefore
  • Forgetting to pass the snapshot as argument
3. Given the following code snippet, what documents will be returned?
const firstPage = await collection.orderBy('name').limit(3).get();
const nextPage = await collection.orderBy('name').startAfter(firstPage.docs[2]).limit(3).get();
medium
A. Documents 1 to 3 on firstPage, documents 4 to 6 on nextPage
B. Documents 1 to 3 on firstPage, documents 3 to 5 on nextPage
C. Documents 1 to 2 on firstPage, documents 3 to 5 on nextPage
D. Documents 1 to 3 on firstPage, documents 1 to 3 again on nextPage

Solution

  1. Step 1: Understand firstPage query

    The first query orders by 'name' and limits to 3 documents, so it returns documents 1, 2, and 3.
  2. Step 2: Understand nextPage query with startAfter

    Using startAfter(firstPage.docs[2]) starts after the third document, so nextPage returns documents 4, 5, and 6.
  3. Final Answer:

    Documents 1 to 3 on firstPage, documents 4 to 6 on nextPage -> Option A
  4. Quick Check:

    startAfter skips last doc, nextPage continues [OK]
Hint: startAfter skips last doc, next page continues from next doc [OK]
Common Mistakes:
  • Assuming startAfter includes the last document again
  • Confusing document indexes (0-based vs 1-based)
  • Not ordering consistently before pagination
4. You wrote this code but it throws an error:
const prevPage = await collection.orderBy('date').endBefore(lastDoc).limitToLast(3).get();
What is the likely cause?
medium
A. Using limitToLast without endBefore causes error
B. You must use startAfter instead of endBefore
C. The lastDoc snapshot is not from the same query order
D. Firebase does not support endBefore with limitToLast

Solution

  1. Step 1: Check cursor snapshot origin

    The snapshot lastDoc must come from a query with the same ordering and filters.
  2. Step 2: Understand error cause

    If lastDoc is from a different query or unordered, Firebase throws an error.
  3. Final Answer:

    The lastDoc snapshot is not from the same query order -> Option C
  4. Quick Check:

    Cursor snapshot must match query order [OK]
Hint: Cursor snapshot must come from same ordered query [OK]
Common Mistakes:
  • Using snapshot from different query or order
  • Mixing startAfter and endBefore incorrectly
  • Ignoring need for consistent ordering
5. You want to implement backward pagination to load previous 5 documents before a known document snapshot currentDoc. Which Firebase query correctly achieves this?
hard
A. collection.orderBy('timestamp').startAfter(currentDoc).limit(5)
B. collection.orderBy('timestamp').endBefore(currentDoc).limitToLast(5)
C. collection.orderBy('timestamp').startAt(currentDoc).limit(5)
D. collection.orderBy('timestamp').endAt(currentDoc).limitToLast(5)

Solution

  1. Step 1: Understand backward pagination

    To load documents before currentDoc, use endBefore(currentDoc).
  2. Step 2: Use limitToLast for correct order

    Using limitToLast(5) returns the last 5 documents before currentDoc in correct order.
  3. Final Answer:

    collection.orderBy('timestamp').endBefore(currentDoc).limitToLast(5) -> Option B
  4. Quick Check:

    Backward pagination uses endBefore + limitToLast [OK]
Hint: Backward pagination = endBefore + limitToLast [OK]
Common Mistakes:
  • Using startAfter for backward pagination
  • Using limit instead of limitToLast when going backward
  • Confusing endBefore with endAt
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard