0

I was looking into Firebase Firestore and what better sample project to create than another chat app.

How I imagine it would work:

  1. Newest messages are fetched when the user enters a fragment
  2. update oldestTimestamp, add messages to recycler view
  3. when user scrolls to top fecthMore and get 20 messages that are older than the current oldest one
  4. update oldestTimestamp, add messages to recycler view

    After reading order-limit-data and query-cursors I came up with those solutions, sadly none of them worked.

I used whereLessThanOrEqualTo("timestamp", previousOldestMessageTimestamp) but this returned 0 messages

After that, I tried using .orderBy("timestamp", Query.Direction.DESCENDING) .endBefore(previousOldestMessageTimestamp) same result as before

Then I tried simplifying the query to just .orderBy("timestamp") .endBefore(previousOldestMessageTimestamp) which returned some messages but in the list were oldest messages in whole conversation

What should I change to make it work properly (as every chat app)?

Also can you explain difference between whereLessThanOrEqualTo() and orderBy() + endBefore()

Here is some context

private var previousOldestMessageTimestamp: Long = -1

private fun firstFetch(){
    //get oldest messages
    //update previousOldestMessageTimestamp to oldest message timestamp
}

 private fun fetchMore() {
    val conversationRef = FirebaseFirestore.getInstance()
                                           .document("conversations")
                                           .collection("some_id")

    conversationRef
            .whereLessThan("timestamp", previousOldestMessageTimestamp) 
            //^ 0 messages

            .orderBy("timestamp", Query.Direction.DESCENDING)
            .endBefore(previousOldestMessageTimestamp)
            //^ returns 0 messages 

            .orderBy("timestamp") 
            .endBefore(previousOldestMessageTimestamp)
            //^ returns messages but starts with oldest one,
            //not what I want

            .limit(20)
            .get().addOnCompleteListener { it: Task<QuerySnapshot!>
                val messages: List<Message> = it.result.map { it.toObject(Message::class.java) }
                println("I fetched ${messages.size} messages : $messages")

                if (messages.isNotEmpty()) {
                    previousOldestMessageTimestamp = *oldestMessage*.timestamp
                }
            }
}
svkaka
  • 3,942
  • 2
  • 31
  • 55
  • 1
    Have you tried **[this](https://stackoverflow.com/questions/50741958/how-to-paginate-firestore-with-android)** solution? – Alex Mamo Aug 05 '18 at 13:12
  • @AlexMamo yes, but I had a problem going to different direction. I expected startAfter to work differently (as it was in realtimeDBS) – svkaka Aug 06 '18 at 09:06

1 Answers1

2

It looks like start/ end work differently than in real-time database so changing

.orderBy("timestamp", Query.Direction.DESCENDING)
.endBefore(previousOldestMessageTimestamp)

to

.orderBy("timestamp", Query.Direction.DESCENDING)
.startAfter(previousOldestMessageTimestamp)

made it work

svkaka
  • 3,942
  • 2
  • 31
  • 55