We’ve found react-redux-firebase (RRF) to be a big time saver when querying Firestore. Despite the name, the library has robust support for not just Firebase, but Firestore too, pulling in redux-firestore behind the scenes for Firestore operations. The documentation for RRF’s use of redux-firestore’s APIs is scant within the RRF docs themselves, but redux-firestore’s documentation is extensive and can be applied to usage of RRF.

Paginating Firestore Queries react-redux-firebase

 

We make use of paginated Firestore queries to infinitely scroll a particularly long list of items. Pagination in Firestore is accomplished through a set of query configuration options that use cursors to determine where to start or end the page of your query. Here’s what redux-firestore’s docs have to say about using a cursor clause to paginate a Firestore query:

STARTAT

Creates a new query where the results start at the provided document (inclusive)

{
collection: ‘cities’,
orderBy: ‘population’,
startAt: 1000000
},

Can only be used with collections. Types can be a string, number, Date object, or an array of these types, but not a Firestore Document Snapshot

The query configuration looks as we’d expect it to, but what about that line in italics? Firestore does allow Document Snapshots as query cursors, but redux-firestore’s docs say that we can’t use them.

That’s a big problem. If we can only supply a simple field value query cursor, what happens if that field value isn’t guaranteed to be unique across documents? We’ll risk adding duplicates if we use startAt, and we’ll risk missing documents if we use startAfter. The former will be an annoyance, but the later is an unacceptable compromise. If we could instead use a Document Snapshot, Firestore will know exactly where to begin our paginated query. Will we have to manually create this query ourselves, dealing with the extra task of setting our data in the store?

The surprising answer is no: because the docs are wrong. redux-firestore does allow Document Snapshots as query cursors. But now we’re left with a bit of a head scratcher – because we’re using redux-firestore to automate fetching data with a Firestore query and update our redux store for us, we don’t have access to the Document Snapshot we’d need to set our cursor.

But there’s another surprise here: we do have access to that Document Snapshot. redux-firestore v0.11.0 introduced an undocumented feature to the library called the Snapshot Cache. Here’s what the PR description says, from developer illuminist:

Get DocumentSnapshot and QuerySnapshot with object from either data or ordered firestore state. If provided with doc data, it will return DocumentSnapshot, providing with a collection from data or an array from ordered state will return QuerySnapshot, except ordered state that generated as DocumentRef will return DocumentSnapshot. Note: the cache is local and, not persistance. Passing an object from initial state or from SSR state will yield undefined.

This sounds like exactly what we’d need to properly paginate our query. So how do we retrieve the Document Snapshot we need from the Snapshot Cache? This feature includes a function called getSnapshotByObject, which takes as its parameter a document object from state.firestore.ordered or state.firestore.data.

Here’s how this looks in practice, using hooks:

And here’s our query:

Precaution should be taken to make sure that items is loaded before calling updateCursor, which can either be called on click, or placed in a useEffect for automatically requerying based on a scroll trigger. In our use case, we build an object of cursors, with a cursor entry being fed to the next query down the line as we connect each page of the query individually for an infinite scroll effect. But for more simple UIs, a solution this concise will work just fine.

Tagged with →  

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share →
DOWNLOAD
DayBack Calendar
DayBack's 30-day trial is unlocked so you can customize it and integrate it with your files.
Download DayBack and we'll send you a couple short emails with tips on how to modify it and use some of the coolest features.
Thank you! Please download: DayBack Calendar
Need More?
SeedCode tips & example files in your inbox
Need More?
SeedCode tips & example files in your inbox
Want More?
Be the first to see articles and tips like these
DOWNLOAD
TimeZync
Download TimeZync and we'll send you a couple short emails with tips syncing your FileMaker Go files.
Thank you! Please download: TimeZync
Want More?
Be the first to see articles and tips like these