Firebase Firestore endBefore() handling for at the end of data

Viewed 239

I want to code a pagination for my app and i meet a problem with endBefore().

Here is my code:

  chatsRef
      .orderBy("createdAt", "desc")
  .endBefore(latestMessage)
  .limit(5)
      .get()
      .then((querySnapshot) =>
        querySnapshot.forEach((documentSnapshot) => {
          console.log(
            {
              ...documentSnapshot.data(),
            }
          );
          latestMessage = {
            ...documentSnapshot.data(),
          };
          
        })
      );

As you can see i set the latestMessage in each function call but the problem is that when the pagination reach the oldest message and set latestMessage with it. The query still get the oldest message again and again. Is there any way for getting null object or not returning any value.

Actually I just want to get to object that is older than latestMessage(latestMessage is not included) but i dont do that anyway.

SIMPLE OUTPUT:

if latestMessage is: (There is one message that is older than that)

Object {
  "_id": "73dd0b64-5fca-452a-9256-4b0bf6879031",
  "createdAt": t {
    "nanoseconds": 161000000,
    "seconds": 1613245061,
  },
  "text": "Dkdodndpdn",
}

But the output return 5 message and 3 of them is newer than latestMessage 1 of them is latestMessage and one of them is the older message

    Object { -->The oldest message
      "_id": "2f1a0537-cfe7-45ac-b284-757dadab48e8",
      "createdAt": t {
        "nanoseconds": 191000000,
        "seconds": 1613230217,
      },
      "text": "rr",
    }

Object { --> Same message with latestMessage
  "_id": "73dd0b64-5fca-452a-9256-4b0bf6879031",
  "createdAt": t {
    "nanoseconds": 161000000,
    "seconds": 1613245061,
  },
  "text": "Dkdodndpdn",
}

Object { -->These 3 messages is newer and i dont want it but it returned by firestore
  "_id": "190f3370-e320-4bc7-bb38-b3e80de60939",
  "createdAt": t {
    "nanoseconds": 601000000,
    "seconds": 1613301778,
  },
  "text": "Se",

}
Object {
  "_id": "fea40c2b-0d94-4445-a5b5-ed9535fd5e52",
  "createdAt": t {
    "nanoseconds": 248000000,
    "seconds": 1613301833,
  },
  "text": "456",
}
Object {
  "_id": "289d2055-e278-4e43-96c1-6a16ccff2d96",
  "createdAt": t {
    "nanoseconds": 972000000,
    "seconds": 1613301912,
  },
  "text": "Sa4",

}
1 Answers

What you see with endBefore(latestMessage) is the expected result because you are getting the new result by starting with the one before the latest message.

A better way to implement pagination is to use startAfter as in this documentation

var first = db.collection("cities")
        .orderBy("population")
        .limit(25);

return first.get().then((documentSnapshots) => {
  // Get the last visible document
  var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1];
  console.log("last", lastVisible);

  // Construct a new query starting at this document,
  // get the next 25 cities.
  var next = db.collection("cities")
          .orderBy("population")
          .startAfter(lastVisible)
          .limit(25);
});
Related