使用Firebase按最新消息对聊天列表进行排序 [英] Sort chat-list by the most recent message with firebase

查看:61
本文介绍了使用Firebase按最新消息对聊天列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么我陷入一个问题,因为 chatList 没有按最后一条消息时间或最新消息进行排序.我已经尝试在数据库中存储 timestamp orderChildBy 时间戳,但是它仍然无法正常工作.不起作用意味着该列表不会在每条消息之后进行排序,并继续将列表显示为在第一条消息之后进行排序.

I don't know why I got stuck in a problem that the chatList is not sorting by the last message time or by the most recent message. I have tried storing timestamp in the database and orderChildBy timestamp but it still not working. not working means the list get not sort after every message and keep showing the list as the sorted after first message.

看看图片上聊天如何混乱!

Look at the image how chats are disordered!

这是我在sendMessage的 ChatActiviy firebaseDatabase 中创建chatList的方式:

This is the way I created chatList in the firebaseDatabase in ChatActiviy on sendMessage:

    val timeAgo = Date().time

    val myTimeMap = HashMap<String, Any?>()
        myTimeMap["timestamp"] = timeAgo
        myTimeMap["id"] = friendId

    val friendTimeMap = HashMap<String, Any?>()
        friendTimeMap["timestamp"] = timeAgo
        friendTimeMap["id"] = currentUserID

    val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).child(friendId)
        chatListSenderReference.keepSynced(true)
        chatListSenderReference.addListenerForSingleValueEvent(object : ValueEventListener{
              override fun onCancelled(p0: DatabaseError) {
              }
              override fun onDataChange(p0: DataSnapshot) {
                       if(!p0.exists()){
                             chatListSenderReference.updateChildren(friendTimeMap)
                       }
    val chatListReceiverReference = dbRef.child("ChatList").child(friendId).child(currentUserID)
        chatListReceiverReference.updateChildren(myTimeMap)
        }
    })

在recyclerView中检索聊天列表时,我试图获取每个用户的用户详细信息,这些用户在数据库中作为currentUser的子级显示.(聊天列表>> CurrentUserId)

On retrieving the chatlist in recyclerView, I am trying to get the users details for each userswho is presented as the child of currentUser in database. (Chatlist>>CurrentUserId)

  private fun retrieveChatList() {

    usersChatList = ArrayList()
    val userRef = dbRef.child("ChatList").child(currentUserID).orderByChild("timestamp")
    userRef.addValueEventListener(object : ValueEventListener
    {
        override fun onCancelled(error: DatabaseError) {
        }

        override fun onDataChange(snapshot: DataSnapshot)
        {
            (usersChatList as ArrayList<String>).clear()
            if (snapshot.exists()){
                for (dataSnapshot in snapshot.children){
                    val userUid = dataSnapshot.key
                    if (userUid != null) {
                        (usersChatList as ArrayList<String>).add(userUid)
                    }
                }
                readChatList()
            }
        }
    })
}

private fun readChatList() {
    mUsers = ArrayList()
    val userRef = FirebaseFirestore.getInstance().collection("Users")
    userRef.get()
            .addOnSuccessListener { queryDocumentSnapshots ->
                mUsers?.clear()
                for (documentSnapshot in queryDocumentSnapshots) {
                    val user = documentSnapshot.toObject(User::class.java)
                    for (id in usersChatList!!){
                        if (user.getUid() == id){
                            (mUsers as ArrayList<User>).add(user)
                        }
                    }
                }
                retrieveGroupChatList()
                chatListAdapter?.notifyDataSetChanged()
                chatListAdapter = context?.let { ChatListAdapter(it, (mUsers as ArrayList<User>), true) }
                recyclerViewChatList.adapter = chatListAdapter

            }.addOnFailureListener { e ->
                Log.d(ContentValues.TAG, "UserAdapter-retrieveUsers: ", e)
            }

}

这是朋友信息的chatListAdapter

And this is the chatListAdapter for friend info

private fun friendInfo(fullName: TextView, profileImage: CircleImageView, uid: String) {
        val userRef = FirebaseFirestore.getInstance().collection("Users").document(uid)
        userRef.get()
                .addOnSuccessListener {
                    if (it != null && it.exists()) {
                        val user = it.toObject(User::class.java)
                Picasso.get().load(user?.getImage()).placeholder(R.drawable.default_pro_pic).into(profileImage)
                fullName.text = user?.getFullName()
            }
        }
    }

这是实时数据库的图片,并且每次我发送或接收消息时间戳时,模型类都为 ChatList .

This is the picture of the realtime database and has a model class as ChatList, every time when I send or receive a message timestamp gets an update.

和另一张Firestore中的用户图片,其模型类为 用户 .

and another picture of Users in the firestore and has a model class as Users .

我有一个可行的解决方案,在这里我在 Firestore Users集合中创建或更新为 lastMessageTimestamp 的字段,以便用户现在可以按 lastMessageTimestamp进行排序.

I have a solution which works, Here i create or update a field as lastMessageTimestamp in the Firestore Users collection so the users now can sort by the lastMessageTimestamp .

   val timeAgo = Date().time
    
        val myFSMap = HashMap<String, Any?>()
            myFSMap["timestamp"] = timeAgo
    
        val friendFSMap = HashMap<String, Any?>()
            friendFSMap["timestamp"] = timeAgo
    
      //firebase chatlist references.
        val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).child(friendId)
        val chatListReceiverReference = dbRef.child("ChatList").child(friendId).child(currentUserID)

      //Firestore Users references.
        val chatListSenderRef = fStore.collection("Users").document(currentUserID)
        val chatListReceiverRef = fStore.collection("Users").document(friendId)
    
        chatListSenderReference.addListenerForSingleValueEvent(object : ValueEventListener{
           override fun onDataChange(p0: DataSnapshot) {
                 if(!p0.exists()){
                    chatListSenderReference.setValue(friendId)
                    //update the timestamp in Users collection
                    chatListSenderRef.update(myFSMap)
                 }
                    chatListReceiverReference.setValue(currentUserID)
                    chatListReceiverRef.update(friendFSMap)

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

在阅读时,我为用户使用 orderBy

And at the time of reading, I use orderBy for Users

 val userRef = FirebaseFirestore.getInstance().collection("Users").orderBy("lastMessageTimestamp" , Query.Direction.ASCENDING)

但这不是完整的解决方案,因为似乎每次消息收发时我都读写 lastMessageTimestamp ,这可能会增加 Firebase Billing 的金额到可怕的数字.所以我仍然需要一个解决方案.

But It is not the complete solution because it seems like that i read and write the lastMessageTimestamp each time on messaging, which can Increase the Firebase Billing Amount to huge scary numbers. so i still need of a solution.

推荐答案

简单的技巧是消息的orderBy ID.因为Firebase生成的ID是基于实时+几个因素的.因此,让我们尝试按ID而不是您的时间戳进行排序.(注意:仅是Firebase生成的ID)

Simple trick is orderBy id of message. Because the id which generated by firebase base on realtime + a few factors. So let's try order by Id instead of ur timestamp. (note: just id which generated by firebase)

这篇关于使用Firebase按最新消息对聊天列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆