I have the 'Next' and 'Previous' buttons. The Next Button is working but when I try to click the Previous button is not working (that method only refresh the document)

Here's my code:

private fun getJob(@Nullable lastPage: DocumentSnapshot?, mode: String?) {

    val db = App.context.db
    val qry: Query?

    if (lastPage == null) {
        qry = db.collection("job")
            .orderBy("createdAt", Query.Direction.DESCENDING)
            .limit(3)
    } else if (mode == "Next") {
        qry = db.collection("job")
            .orderBy("createdAt", Query.Direction.DESCENDING)
            .startAfter(lastPage)
            .limit(3)
    } else {
        qry = db.collection("job")
            .orderBy("createdAt", Query.Direction.DESCENDING)
            .endBefore(lastPage)
            .limitToLast(3)
    }

    qry.get().addOnSuccessListener { snapshot ->
        mPage = snapshot.documents[snapshot.size() - 1]
    }

Solution 1:

It seems like lastPage in your code is the last document on the current page. So that means that if you run this code for the next page:

qry = db.collection("job")
    .orderBy("createdAt", Query.Direction.DESCENDING)
    .startAfter(lastPage)
    .limit(3)

You get the document starting after the last document on the current page, which is exact what you want.


But when you run this code to get the previous page:

qry = db.collection("job")
    .orderBy("createdAt", Query.Direction.DESCENDING)
    .endBefore(lastPage)
    .limitToLast(3)

You're getting (up to) 3 documents before the last document on the current page. So you end up with two of the same documents as you're currently showing.


To paginate in Firestore you need to know the anchor document. To paginate forward, that anchor document is the last document of the previous page as you currently have, but to paginate backward you need to know the first document of the current page instead, so you'll need to track that.

Once you track the first document too, the query becomes:

qry = db.collection("job")
    .orderBy("createdAt", Query.Direction.DESCENDING)
    .endBefore(firstDocumentOnCurrentPage)
    .limitToLast(3)