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]