1

I'm trying to implement a pagination system using Firebase Firestore startAfter() and limit() query methods. The first query is returned successfully, but the second one returns an empty snapshot.

  • Here's my getNextPage() method :

    fun getNextPage(paginationSize : Long) : TrendingRepository {
    database.collection("app")
        .document("data")
        .collection("offers")
        .orderBy("discount")
        .startAfter(lastVisible)
        .limit(paginationSize)
        .get().addOnSuccessListener { snapshot ->
    
            Log.i("TrendingRepo", "pagination size : $paginationSize")
            val newList = ArrayList<Offer>()
    
            if (!snapshot.isEmpty) {
                lastVisible = snapshot.documents[snapshot.size() - 1]
            }
    
            for (document in snapshot) {
                val item = document.toObject(Offer::class.java)
                newList.add(item)
                Log.i("TrendingRepo", "at position: ${newList.indexOf(item)} got item: ${item.id}")
            }
    
            successListener?.onSuccess(newList)
    
        }.addOnFailureListener {
            failureListener?.onFailure(it.localizedMessage)
        }
    
    return this
    }
    
  • here's my Logcat :

TrendingRepo: pagination size : 48 // first try

TrendingRepo: at position: 0 got item: 0pqcRzSd06WWlNNmcolu

TrendingRepo: at position: 1 got item: 7I7wiSYt5yEBWwN08bqJ

...

TrendingRepo: at position: 45 got item: 4B3dEPhFLqhKrYpLWYE7

TrendingRepo: at position: 46 got item: 4ddLqiGe8ReXW8SKq2Q6

TrendingRepo: at position: 47 got item: 4uVnnGNAmKvGUUHcV01n

TrendingRepo: pagination size : 48 // second try

//no more logging, data is empty

Android
  • 1,420
  • 4
  • 13
  • 23
Tamim Attafi
  • 2,253
  • 2
  • 17
  • 34
  • Check **[this](https://stackoverflow.com/questions/50741958/how-to-paginate-firestore-with-android)** out. Is Java code but hope it helps. – Alex Mamo Jun 24 '19 at 06:52

1 Answers1

1

There may be a case in which the items are less than the pagination size So here is the code

private var lastVisible: DocumentSnapshot? = null
private var isLastPage: Boolean = false
private var isDocEmpty: Boolean = false

var ref: Task<QuerySnapshot>? = null

 if (lastVisible != null) {
ref = database.collection("app").document("data").collection("offers").orderBy("discount").startAfter(lastVisible).limit(paginationSize).get()
 } else {
ref = database.collection("app").document("data").collection("offers").orderBy("discount").limit(paginationSize).get()
 }


 ref.addOnSuccessListener { documents ->

            hideProgress()
            isDocEmpty = documents.isEmpty



            if (!isDocEmpty) {
                lastVisible = documents.last()
                isLastPage = documents.size() < paginationSize
            }

            isLoading = false
        }
            .addOnFailureListener { exception ->
                Log.w("TAG", "Error getting documents: ", exception)
                isLoading = false
                hideProgress()
            }

I hope this will helps you.

Sunny
  • 3,134
  • 1
  • 17
  • 31
  • 1
    The items are successfully loaded, I used => if (lastVisible != null) { newQuery = newQuery.startAfter(lastVisible!!) } and then set the limit and get the page. I was about to break my MVP architecture and switch to FirestorePagingAdapter, Thank you! I'm already using isLoading and allData booleans in my custom adapter. – Tamim Attafi Jun 25 '19 at 11:39