How can I paginate in descending order by child value with firebase?

I posted this question after a long day of coding and my brain was mush.

I took another crack at it this morning, and as is so often the case, was able to find the solution rather quickly.

Solution:

In order to paginate data, we need the ability to arbitrarily pull sorted data from the middle of a list. You can do this using the following functions provided by the firebase API:

startAt

endAt

limitToFirst

limitToLast

More information can be found here.

In my case, since I need my data in descending order, I'll use endAt and limitToLast.

Assuming I'd like each of my pages to have five items. I would write my first query like so:

ref.orderByChild('votes')
    .limitToLast(5)
    .once('value', function(snapshot) {
      console.log('Snap: ', snapshot.val());
    });

This gets the 5 items with the highest number of votes.

In order to get the next page, we'll need to store two pieces of data from the results of our last query. We need to store the number of votes, and key for the item that had the least number of votes. That is to say, the last item in our list.

Using that data, our next query, and all subsequent queries, would look as follows:

ref.orderByChild('votes')
    .endAt(previousVoteCount, previousKey)
    .limitToLast(5)
    .once('value', function(snapshot) {
      console.log('Snap: ', snapshot.val());
    });

You'll notice in this query I added endAt. This gets the next 5 items with the most votes starting from the last one in the previous list. We must include the the key for the last item in the previous list so that if there are multiple items with the same number of votes, it'll return a list beginning with the correct item, and not the first one it finds with that number of votes, which could be somewhere in the middle of the list you got from the initial query.

That's it!