如何按最新消息对聊天列表进行排序?

Posted

技术标签:

【中文标题】如何按最新消息对聊天列表进行排序?【英文标题】:How can I sort chat list by the most recent message? 【发布时间】:2021-02-27 15:12:34 【问题描述】:

我不知道为什么我遇到了 chatList 没有按最后消息时间或最近消息排序的问题。我已尝试将 timestamp 存储在数据库中并使用 orderChildBy 时间戳,但它仍然无法正常工作。

这就是我在firebaseDatabase 中创建聊天列表的方式

    val timeAgo = Date().time

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

    val friendTimeMap = HashMap<String, Any?>()
        friendTimeMap["timestamp"] = timeAgo.toString()
        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 中检索聊天列表

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

            override fun onDataChange(snapshot: DataSnapshot)
            
                (mUsers as ArrayList).clear()
                snapshot.children.forEach 
                    val userUid = it.key
                    if (userUid != null) 
                        (mUsers as ArrayList).add(User(uid = userUid))
                    
                
                retrieveGroupChatList()
                chatListAdapter?.notifyDataSetChanged()
                chatListAdapter = context?.let  ChatListAdapter(it, (mUsers as ArrayList<User>), true) 
                recyclerViewChatList.adapter = chatListAdapter
            
        )

这是数据库的图片,每次我发送或接收消息时时间戳都会更新。

【问题讨论】:

【参考方案1】:

你应该存储消息的时间戳,然后使用val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).orderByChild("timestamp")

【讨论】:

您在添加时间戳后尝试val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).orderByChild("timestamp") 吗?希望它能解决您的问题。 是的,我在 recyclerView 中检索数据时尝试过,但没有任何反应。 我忘记添加friendId。试试这个val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).child(friendId).orderByChild("timestamp") 如果我们转到 currentUserId 的子项,这将不起作用,那么总会有朋友的字段或数据,而不是 currentUser 与之交谈过的用户列表。【参考方案2】:

不确定这是否适用于您的情况,但对于我的聊天应用程序,我有一个消息列表,我所做的只是对列表进行排序

 //sort method - takes a list to be sorted
private fun sortMessagesByDate(messages: MutableList<Message>) 

    //sort messages by Date
    messages.sortWith(compareBy  it.timestamp )

联系人列表的循环方法

 // method for obtaining contacts and adding them to the lists
private fun getAllContacts() 
    val currentUserPhoneCredential = auth.currentUser?.phoneNumber!!

    firestore.collection("Contacts")
        .whereNotEqualTo("phoneNumber", currentUserPhoneCredential)
        .get().addOnSuccessListener  querySnapshot ->
        for (doc in querySnapshot) 

            val user = doc.toObject(User::class.java)
 //I have 2 lists one with just the names and another with the User Object
            contactsList.add(user)
            contactsNames.add(user.name!!)

        
        adapter.notifyDataSetChanged()
    

然后在 ListView 的 Adapter 上传入 Names List(contactsNames)

 adapter =
        ArrayAdapter(requireActivity(), android.R.layout.simple_list_item_1, contactsNames)

之后,当在特定位置单击名称时,应用程序导航到 DisplayMessage 片段,并获取与单击的联系人对应的 UserObject。

//implement listView onClick
    binding.listView.setOnItemClickListener  _, _, i, _ ->


       /*when a name is clicked on the ListView at a specific position the app navigates
        to the DisplayMessage Fragment taking a UserObject corresponding to the
         clicked contact.*/
        findNavController().navigate(ChatFragmentDirections
                                         .actionChatFragmentToMessageFragment(contactsList[i]))

    

您还可以使用 RecyclerView 来显示联系人的姓名。

【讨论】:

这样排序邮件!?不是聊天列表。 嘿,小伙子,你能告诉我你是如何为你的聊天应用制作聊天列表的(聊天列表是指当前用户与之聊天的人的列表。) 你好@Mr. Groot,为此,我必须将您推荐给我的项目 GIT Repo 并在代码中包含 cmets。点击此链接,将看到 ChatFragment,其中包含 ChatList github.com/Fanadezz/WhatsAppClone/tree/master/app/src/main/java/… 的代码 Tonnie 对不起,我没有找到任何聊天列表的代码。 我基本上首先在注册时将联系人列表(包含用户详细信息)保存在 Firebase Firestore 上。然后我循环 ContactList 以获取每个用户,但从列表中省略当前用户。然后我在 ListView 上填充 ContactList。上面已经添加了这段代码。

以上是关于如何按最新消息对聊天列表进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何按插入时间对 Meteor 集合进行排序?

如何获取按最近提交排序的 Git 分支列表?

如何以字符串格式按日期对对象列表进行排序?

聊天消息排序不正确

如何按 id 或月份对数组进行排序:降序(最新帖子优先)?

核心数据聊天应用获取一批按日期排序的消息