Firestore pagination by offset

*爱你&永不变心* 提交于 2021-01-20 12:08:05

问题


I would like to create two queries, with pagination option. On the first one I would like to get the first ten records and the second one I would like to get the other all records:

.startAt(0)
.limit(10)

.startAt(9)
.limit(null)

Can anyone confirm that above code is correct for both condition?


回答1:


Firestore does not support index or offset based pagination. Your query will not work with these values.

Please read the documentation on pagination carefully. Pagination requires that you provide a document reference (or field values in that document) that defines the next page to query. This means that your pagination will typically start at the beginning of the query results, then progress through them using the last document you see in the prior page.




回答2:


As Doug mentioned, Firestore does not support Index/offset - BUT you can get similar effects using combinations of what it does support.

Firestore has it's own internal sort order (usually the document.id), but any query can be sorted .orderBy(), and the first document will be relative to that sorting - only an orderBy() query has a real concept of a "0" position.

Firestore also allows you to limit the number of documents returned .limit(n)

.endAt(), .endBefore(), .startAt(), .startBefore() all need either an object of the same fields as the orderBy, or a DocumentSnapshot - NOT an index

what I would do is create a Query:

const MyOrderedQuery = FirebaseInstance.collection().orderBy()

Then first execute

MyOrderedQuery.limit(n).get()

or

MyOrderedQuery.limit(n).get().onSnapshot()

which will return one way or the other a QuerySnapshot, which will contain an array of the DocumentSnapshots. Let's save that array

let ArrayOfDocumentSnapshots = QuerySnapshot.docs;

Warning Will Robinson! javascript settings is usually by reference, and even with spread operator pretty shallow - make sure your code actually copies the full deep structure or that the reference is kept around!

Then to get the "rest" of the documents as you ask above, I would do:

MyOrderedQuery.startAfter(ArrayOfDocumentSnapshots[n-1]).get()

or

MyOrderedQuery.startAfter(ArrayOfDocumentSnapshots[n-1]).onSnapshot()

which will start AFTER the last returned document snapshot of the FIRST query. Note the re-use of the MyOrderedQuery

You can get something like a "pagination" by saving the ordered Query as above, then repeatedly use the returned Snapshot and the original query

MyOrderedQuery.startAfter(ArrayOfDocumentSnapshots[n-1]).limit(n).get() // page forward
MyOrderedQuery.endBefore(ArrayOfDocumentSnapshots[0]).limit(n).get() // page back

This does make your state management more complex - you have to hold onto the ordered Query, and the last returned QuerySnapshot - but hey, now you're paginating.

BIG NOTE

This is not terribly efficient - setting up a listener is fairly "expensive" for Firestore, so you don't want to do it often. Depending on your document size(s), you may want to "listen" to larger sections of your collections, and handle more of the paging locally (Redux or whatever) - Firestore Documentation indicates you want your listeners around at least 30 seconds for efficiency. For some applications, even pages of 10 can be efficient; for others you may need 500 or more stored locally and paged in smaller chucks.




回答3:


From CollectionReference:

offset(offset) → {Query}

Specifies the offset of the returned results.



来源:https://stackoverflow.com/questions/62951311/firestore-pagination-by-offset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!