Maramal
Maramal

Reputation: 3466

Firebase Real time database pagination

I am trying to add some pagination functionality to my Express + Firebase Realtime Database SDK but I am not sure how to achieve this, and the documentation is not helping me. Also, all the examples I found are regarding Firestore.

Just as an example I have this model User which is accessed by database.ref('users'). Imagine I have 10 users whose IDs go from 1 to 10 respectively and I want to paginate 5 per page.

What I expect is get users whose keys go from 1 to 5, and then when someone clicks on page 2, it will get users whose keys go from 6 to 10.

According to the documentation, I understood that I should add something like the following:

(req, res) => {
    const { key } = req.query;
    let ref = database.ref('users')
                  .orderByChild('createdAt')
                  .limitToLast(5);
    if (key) { 
        ref = ref.startAt(key);
    }

    ref.once('value')
        .then(snapshot => ...);
}

What I get until now is that the difference between limitToLast() and limitToFirst() is the sorting, it's like ORDER BY createdAt DESC and ORDER BY createdAt ASC respectively.

If I set ref.startAt(5), the previous code doesn't work since I am getting the first five users (1 to 5).

What approach should I use? Thanks in advance.

Edit:

I got that if I do database.ref('users').orderByChild('createdAt').limitToLast(5).startAt(5) I get documents where createdAt is greater that 5 which is wrong. I should sort by date after getting those documents whose keys are next to 5.

Upvotes: 3

Views: 3579

Answers (1)

I was struggling with a very similar scenario, although in reverse - I wanted to display the last 10 records, and then paginate to the beginning of the list (in my case the list was ordered by date, and I wanted to display the latest dates first);

For your example however, I was able to paginate from 1-5, then 6-10 by implementing the following:

First 5 Users:

database
  .ref('users')
  .orderByChild('createdAt')
  .limitToFirst(6) //Note here that the request is for the first 6 results
  .once("value")
  .then((snap) => {
    const firstSix = snap.val();
    const sixth = firstSix[5].createdAt; //assuming your data is an array, get the last entry


    const startAtNext =  sixth, //this is the 6th value used for pulling the next 5 results - this should be stored globally
    const currentUserList = firstSix.slice(0, firstSix.length -1), //the list of users 1-5
});

And for the next 5 users:

database
  .ref('users')
  .orderByChild('createdAt')
  .startAt(startAtNext) // Globally stored variable from first call
  .limitToFirst(6) //Note here that the request is for the first 6 results
  .once("value")
  .then((snap) => {
    const nextSix = snap.val();
    const sixth = nextSix[5].createdAt; //assuming your data is an array, get the last entry


    const startAtNext =  sixth, // the start index for the next request
    const currentUserList = firstSix.slice(0, firstJobsList.length -1), //the next 5 users
});

Upvotes: 2

Related Questions