7

I am new to firebase and a I am trying the pagination query. I like to have a 'Next' and 'Previous' buttons. My next button is working fine, my issue is when clicking Previous

Reference: https://firebase.google.com/docs/firestore/query-data/query-cursors

Currently, I have 10 documents on my collection and I like to display 3 at a time.

On load I display 3 items only

       var first = db.collection("employees").limit(3);
        first.get().then(function (documentSnapshots) {
        documentSnapshots.docs.forEach(doc => {
            //function to display in the HTML
            renderEmployee(doc);
        });
        lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];
    });

Next Button

$("#js-next").on('click', function () {
        $('#employee-table tbody').html('');
        var next = db.collection("employees")
            .startAfter(lastVisible)
            .limit(3);
        next.get().then(function (documentSnapshots) {
            documentSnapshots.docs.forEach(doc => {
                //function to display in the HTML
                renderEmployee(doc);
            });
            lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];
firstVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];
        });
    });

Previous (CODE PROBLEM)

    $("#js-previous").on('click', function () {
        $('#employee-table tbody').html('');
        var previous = db.collection("employees")
            .startAt(firstVisible)
            .limit(3);
        previous.get().then(function (documentSnapshots) {
            documentSnapshots.docs.forEach(doc => {
                renderEmployee(doc);
            });
        });
    });

I am using the variable firstVisible at startAt and I am setting its value when clicking the next button but clicking it does not work as expected.

To be honest I am not sure what I need to set on the firstVisible variable to get the previous document snapshot

Any help will be appreciated

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Dave
  • 193
  • 1
  • 19

3 Answers3

11
$("#js-previous").on('click', function () {
    $('#employee-table tbody').html('');
    var previous = db.collection("employees")
        .endBefore(firstVisible)
        .limitToLast(3);
    previous.get().then(function (documentSnapshots) {
        documentSnapshots.docs.forEach(doc => {
            renderEmployee(doc);
        });
    });
});

Try to use endBefore with limitToLast. limitToLast will return the last documents right before the first visible document. Hope this help!

Danh Nguyen
  • 308
  • 3
  • 9
1

Firestore pagination is based on knowing the anchor document: the document that the two pages involved are anchored on.

Usually this would be the last document of the current page, which is also the first document of the next page. Or actually if you'd use startAfter() it'd be the document just before the next page.

But since you're paginating backwards, the anchor document is the first document on the current page, which is also the last document on the previous page. This means you'll need to:

  1. Reverse the sort order of the query.
  2. Start at (or after) the anchor document.

So something like:

var previous = db.collection("employees")
    .orderBy(firebase.firestore.FieldPath.documentId(), "desc")
    .startAt(firstVisible)
    .limit(3);
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • thanks for the input, is my first Visible value is okay and does not require changes? – Dave Aug 27 '19 at 13:49
  • Uncaught ReferenceError: Query is not defined May I know where query will come from? – Dave Aug 27 '19 at 15:45
  • Oops... that `"desc"` in JavaScript. See https://firebase.google.com/docs/firestore/query-data/order-limit-data – Frank van Puffelen Aug 27 '19 at 18:57
  • Hi! I try the updated orderBy but I got error Invalid query. Expected a string for document ID in Query.startAt(), but got a number – Dave Aug 28 '19 at 00:59
  • Hmmm.... the syntax seems correct according to other questions, such as this one: https://stackoverflow.com/questions/48466028/query-firebase-firestore-documents-by-the-id – Frank van Puffelen Aug 28 '19 at 02:33
  • I will check, I think there is an issue on the First Visible variable – Dave Aug 28 '19 at 02:43
  • I think the startAt is the issue and not the orderBy by the way the value of last Visible and firstVisible is same – Dave Aug 28 '19 at 03:15
0

Change startAt to endBefore:

$("#js-previous").on('click', function () {
    $('#employee-table tbody').html('');
    var previous = db.collection("employees")
        .endBefore(firstVisible)
        .limit(3);
    previous.get().then(function (documentSnapshots) {
        documentSnapshots.docs.forEach(doc => {
            renderEmployee(doc);
        });
    });
});
Skully
  • 2,882
  • 3
  • 20
  • 31
Miriam
  • 337
  • 3
  • 6
  • While this code may solve the question, [including an explanation](https://meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Brian61354270 Apr 13 '20 at 18:27
  • Hi! What will be the value of firstVisible? right now on my code it is same value of lastVisible – Dave Apr 19 '20 at 05:03