0

I'm trying to realize pagination with Firestore with filtering + ordering on the frontend but page items must be loaded after click on needed page instead of loading all data and paginating it in browser.

The one option to paginate data in Firestore is cursors where I need to know concrete element (DocumentSnapshot.data()) to request startAfter/startAt/endAt/endBefore to load next page OR the field values to start this query at, in order of the query's order by.

  1. What if I need to load the 3rd page of 10?
  2. How could I know what pages are there without fetching all items?
  3. And the main question - on what element I should paginate with startAfter?

Now my code works with such algorithm: on every change filter/order I fetch ALL users from Firestore such as on initial fetch and calculate what element I should use in startAfter when loading any of pages. Well, this method works, but it defeats the purpose of pagination. It is very bad practice, but workable.

P.S. there is a method offset in cloud-firestore backend library but on the frontend library it is absent. And there is an issue on github says it couldn't be realized on front. one

seclace
  • 98
  • 7

1 Answers1

1

What if I need to load the 3rd page of 10?

If you intent to use infinite scroll, to access the 3rd page, you should scroll down till you reach the 3rd page. If this is not what you want, then you should implement the classic pagination algorithm, where you should get the total number of items, divide it by the number of items per page and display Page1, Page 2 and so on. In my opinion, the first approach is more elegant since all web/mobile apps use it.

How could I know how many pages are there?

According to the number of items you want to have o a page, you can determine the number of pages.

pageNumber = totalNumberOfItems/numberOfItemsPerPage

And the main question - on what element I should paginate with startAfter?

There is no fixed number for that. You should choose that number according to your app use-case. The most important thing is that the number must be grater than the total number of items you want to display on a page. So let's say the total number of items that fit on a page on a page is 10, then the number should be 12 or 15.

Edit:

I'm trying to realize pagination with Firestore with filtering + ordering on the frontend but page items must be loaded after click on needed page instead of loading all data and paginating it in browser.

When talking about pagination, it means that we talk about how to get data in smaller chunks instead of loading all the data on the client. This means that instead of getting all data we get a small part of it one of a time. So initially we create a request to get the data using a call to limit(15) function so we can get only 15 elements. Once you get those 15 element, on button click, load other 15 elements and so on till your each the end.

If you know Android, I recommend you see my answer this post, where I have explained a recommended way in which you can paginate queries by combining query cursors with the limit() method on button click.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thanks for the response. You described the common idea of pagination. I agree with you. Also I like infinite scroll instead of classic paging. I extended my question description and clarify what I want - pagination + filtering + ordering by requests. Frontend is only view. Frontend must not have any own filtering or ordering or pagination. – seclace Feb 20 '19 at 10:36
  • I understand so please see my updated answer. Is it ok now? – Alex Mamo Feb 20 '19 at 10:58
  • May be I am not clear enough but it is not ok now. With classic paging mode you have ability to load any of available pages, i.e. there are 50 items and I want to load from 30 to 40 items. With Firestore I use `startAfter()` and `limit(10)`, so with your solution I can load 4th page only after 1-3 pages. I need to load it by the second request. No more fetches. – seclace Feb 20 '19 at 11:12
  • I've read your explanation before and it was a good starting point for me. – seclace Feb 20 '19 at 11:13
  • If you want to directly access the 3rd page, then you should use `startAt(30)` and `endAt(40)` functions so you can get the desired behaviour, right? – Alex Mamo Feb 20 '19 at 11:29
  • Right. But Firestore does not support accessing startAt/endAt/startAfter/endBefore by order number. As per docs says: parameter of these methods is `snapshotOrVarArgs` and its description is `The snapshot of the document you want the query to start at or the field values to start this query at, in order of the query's order by.` So there is no option to make offset by `startAt(30)` and `endAt(40)`. – seclace Feb 20 '19 at 11:37
  • You're right, there is not but you can add it, so you can jump exactly to the desired page. Otherwise, load one page at a time, right? – Alex Mamo Feb 20 '19 at 11:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188750/discussion-between---and-alex-mamo). – seclace Feb 20 '19 at 11:48
  • Please also take a look the Doug's answer from this [post](https://stackoverflow.com/questions/53131171/firestore-get-a-range-of-documents-by-row-number). Check also [this](https://www.youtube.com/watch?v=poqTHxtDXwU) out. Can I help you with other details? – Alex Mamo Feb 20 '19 at 13:39