How to sortByChild("Timestamp") on a hashmapped recyclerview

Viewed 42

So I am following this firebase + kotlin chatting app guide. All is fine but the message list is not sorted by timestamp,

I have read through other sources and it says the only way is by using sortByChild("timestamp") but it still will not sort.

Below is the code:

// creating hashmap for each message
val latestMessagesMap = HashMap<String, ChatMessage>()

    //creating adapter
    private fun refreshRecyclerViewMessages() {
        adapter.clear()
        latestMessagesMap.values.forEach {
            adapter.add(DaftarPesan(it))
        }
    }

    //start creating recycler view
    private fun listenForLatestMessages() {
        val fromId = FirebaseAuth.getInstance().uid

        // get Firebase database path
        val ref = FirebaseDatabase.getInstance().getReference("/pesan-terakhir-pengguna/$fromId")

        // sort by timestamp for each message
        ref.orderByChild("timestamp").addChildEventListener(object: ChildEventListener {
            override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
                if (snapshot.exists()) {
                    val chatMessage = snapshot.getValue(ChatMessage::class.java) ?: return
                    latestMessagesMap[snapshot.key!!] = chatMessage

                    //use the adapter
                    refreshRecyclerViewMessages()
                } else {
                }
            }
            override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
                val chatMessage = snapshot.getValue(ChatMessage::class.java) ?: return
                latestMessagesMap[snapshot.key!!] = chatMessage
                refreshRecyclerViewMessages()
            }

            override fun onChildRemoved(snapshot: DataSnapshot) {
            }
            override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
            }
            override fun onCancelled(error: DatabaseError) {
            }
        })
    }

    val adapter = GroupAdapter<GroupieViewHolder>()

And here is the ViewHolder class:

//starting with viewolder class
class DaftarPesan(val chatMessage: ChatMessage): Item<GroupieViewHolder>( ) {
    var chatPartnerUser: DataProfilUsaha? = null

    override fun bind(viewHolder: GroupieViewHolder, position: Int) {

        val chatPartnerId: String


        // getting the sender uid
        if (chatMessage.fromId == FirebaseAuth.getInstance().uid) {
            chatPartnerId = chatMessage.toId
        } else {
            chatPartnerId = chatMessage.fromId
        }

        // getting the sender's profile picture and name
        val ref = FirebaseDatabase.getInstance().getReference("/profile/$chatPartnerId")
        ref.addListenerForSingleValueEvent(object: ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                if (snapshot.exists()) {
                    chatPartnerUser = snapshot.getValue(ProfileData::class.java)
                    
// putting sender name to text view
viewHolder.itemView.daftar_nama_pengirim_pesan_pedagang.text =
                        chatPartnerUser?.namaUsaha


                    val targetImageView = viewHolder.itemView.picture_daftar_pesan_pedagang
                    Picasso.get().load(chatPartnerUser?.coverImageUrl).into(targetImageView)
                } else {

                }
            }

            override fun onCancelled(error: DatabaseError) {
            }
        })


    }

And here is the database structure:

"pesan-terakhir-pengguna": {
    "76UJp5x9WcdH94os8s9q952uI2": {
      "B4ftYzLXLcOsDiChjMAXOgnBnar1": {
        "fromId": "P6scAzLXLcOsDiChjMAXOgnBnar1",
        "id": "-NBXTFVboixKDNepRIhD",
        "text": "test",
        "timestamp": 1662730703,
        "toId": "76UJp5x9WcdH94os8s9q952uI2"
      }
    }

Here is the rules on firebase:

{
  "rules": {
    ".read": auth != null,
    ".write": auth != null,
      "pesan-terakhir-pengguna": {
        "$uid": {
          ".indexOn": "timestamp"
        }
      }
  }
}

Here is the log cat when the message recycler view is created.

2022-09-11 20:46:46.974 18714-18714/com.example.gesit I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: windowingMode=1 isFullscreen=true isPopOver=false isHidden=false skipActivityType=false isHandlerType=true this: DecorView@bfc1c4[MainScreen]
2022-09-11 20:46:46.992 18714-18714/com.example.gesit I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: windowingMode=1 isFullscreen=true isPopOver=false isHidden=false skipActivityType=false isHandlerType=true this: DecorView@bfc1c4[MainScreen]
2022-09-11 20:46:47.020 18714-18714/com.example.gesit I/ViewRootImpl@fdb127d[MainScreen]: ViewPostIme pointer 1
2022-09-11 20:46:47.020 18714-18714/com.example.gesit I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: windowingMode=1 isFullscreen=true isPopOver=false isHidden=false skipActivityType=false isHandlerType=true this: DecorView@bfc1c4[MainScreen]

0 Answers
Related