3

I have a list of offers/deals saved in my firestore database. I want to fetch the first 3 deals sorted by discount in desc order i.e the deals with highest discount comes first and then next highest and so on. I am fetching them in segments of 3.

How i sorted them firebase console

My sorted database based on discount

I am trying to achieve the same using android code. So, that the first 3 elements with discount 55,44,28 should come first, later 27,27,21 and finally 19,4.

class ContentGenerationActivityV1 : AppCompatActivity() {

     var lastDocument : DocumentSnapshot?= null
     lateinit var filterQuery: Query

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_content_generation)

        val doc = FirebaseFirestore.getInstance().collection("steal-deals").document("deals")

       filterQuery = doc.collection(getTodayTimeStamp().toString())
        .orderBy("discount", Query.Direction.DESCENDING)

       filterFetchButton.setOnClickListener {
           if(lastDocument == null){
              fetchFirstFew()
           } else {
            fetchMore()
        }
    }
}

//Get first 3 elements
fun fetchFirstFew(){

    Log.d("N/W CALL ::", "FIRST")

    filterQuery.limit(3) .get()
        .addOnSuccessListener { result ->

            lastDocument = result.documents.last()

            for (document in result) {
                Log.d("DEAL :: ", "${document.id} => ${document.data}")
            }

        }


}

//Get the next 3 elements
fun fetchMore(){

    Log.d("N/W CALL ::", "SECOND")

    filterQuery.startAfter(lastDocument)
        .limit(3).get()
        .addOnSuccessListener { result ->

            lastDocument = result.documents.last()

            for (document in result) {
                Log.d("DEAL :: ", "${document.id} => ${document.data}")
            }


        }
}

But it is always returning the first three elements (55,44,28) no matter what.enter image description here

Please guide me so in achieving the same.

Shweta Chauhan
  • 6,739
  • 6
  • 37
  • 57
Saurabh Padwekar
  • 3,888
  • 1
  • 31
  • 37

3 Answers3

2

I had the same problem but after some research found out the "startAfter(lastDocument)" returns a new Query instance which you need to get and on that you need to call limit.

val query = filterQuery.startAfter(lastDocument)
query.limit(3).get().addOnSuccessListener {}
Ishaan
  • 3,658
  • 2
  • 23
  • 39
1

In addition to storing query object in separate reference, you also need to make sure that you are passing the non-null lastDocument to startAfter. You can either cast it to as Document Snapshot or put !! at the variable end

filterQuery.startAfter(lastDocument!!)
    .limit(3).get()

OR

filterQuery.startAfter(lastDocument as DocumentSnapshot)
    .limit(3).get()

It will surely work

Jalees Mukarram
  • 106
  • 1
  • 4
0

i just got this issue.

reference

so, in your code

Wrong:

filterQuery.limit(3) .get()
        .addOnSuccessListener { result ->

            lastDocument = result.documents.last()

            for (document in result) {
                Log.d("DEAL :: ", "${document.id} => ${document.data}")
            }

        }

True:

filterQuery = filterQuery.limit(3) .get()
        .addOnSuccessListener { result ->

            lastDocument = result.documents.last()

            for (document in result) {
                Log.d("DEAL :: ", "${document.id} => ${document.data}")
            }

        }

because when you chaining to query, it creates and returns a new Query that starts after the provided document (exclusive). so you have to reassign it!

Ryan M
  • 18,333
  • 31
  • 67
  • 74
Jetwiz
  • 642
  • 7
  • 14