【问题标题】:How to avoid for picking up already existing Database Node --Recyclerview Items如何避免拾取已经存在的数据库节点--Recyclerview Items
【发布时间】:2020-09-07 08:49:31
【问题描述】:

我面临的问题是在更新用户消息详细信息时,例如用户是否看到消息,firebase 使用以前的消息 ID 创建节点并导致在聊天应用程序中创建空文本。

我的聊天工作流程是:

--在使用 Groupie Recyclerview 向另一个用户发送消息时,我创建了一个单独的引用,父节点作为“消息”。看起来是这样的

val ref = FirebaseDatabase.getInstance().getReference("/Messages/$fromId/$toId")
val toRef = FirebaseDatabase.getInstance().getReference("/Messages/$toId/$fromId")

fromId -- 当前用户 toId -- 向另一个收件人发送消息

在发送消息时,还有另一个函数将通过识别 ChatFromItem Adapter 和 ChatToItem Adapter 来从两端拾取侦听消息。

在 ChatTo 适配器中,我编写了获取所见状态的逻辑

  toRef.addListenerForSingleValueEvent(object :ValueEventListener{
    override fun onCancelled(p0: DatabaseError) {
        TODO("Not yet implemented")
    }

    override fun onDataChange(p0: DataSnapshot) {

        for (ds in p0.children) {

            val fromuserupdate = HashMap<String,String>()

            if (chatMessage.fromId != FirebaseAuth.getInstance().uid && chatMessage.toId == FirebaseAuth.getInstance().uid){


                val Totoken = ds.child("tokey").value.toString()

                val Frommessageid = ds.child("fromkey").value.toString()


                val toUserChatRef = FirebaseDatabase.getInstance().getReference("users-messages").child(fromId).child(toId).child(Totoken)

                val fromUserref = FirebaseDatabase.getInstance().getReference("users-messages").child(toId).child(fromId).child(Frommessageid)

                                                    fromuserupdate.put("messageseen","true")

                fromUserref.updateChildren(fromuserupdate as Map<String,Any>).addOnCompleteListener { }
                toUserChatRef.updateChildren(fromuserupdate as Map<String,Any>).addOnCompleteListener { }

                ChatFromItem

                fromUserref.removeEventListener(this)
                toUserChatRef.removeEventListener(this)


            }

        } })

当尝试向第一次发送新消息时,我可以毫无问题地更新 Seen 状态,但是当我尝试发送另一条消息时,逻辑会拾取旧消息数据库路径并创建另一个节点,这会导致聊天应用程序中出现任何空值当我再次进行任何活动并返回 ChatActivity 时,它会创建带有 Null 的附加节点。

这里我使用的消息被视为字符串而不是布尔值。

我的数据库输出

"users-messages" : {
"4bgqdomQZlRIFnq9lHtKE78wyrv2" : {
  "f4b3phpVJnTByNt2vgCKnKRuxc82" : {
    "-M7nbxCZ3WwPGFcLRMGx" : {
      "messageseen" : "true"
    },
    "-M7nbxCakllN4LvLsOQ0" : {
      "fromId" : "f4b3phpVJnTByNt2vgCKnKRuxc82",
      "fromkey" : "-M7nbxCZ3WwPGFcLRMGx",
      "fulldate" : "21/05/2020",
      "message" : "hi",
      "messageseen" : "true",
      "timespot" : " 01:16 AM",
      "timestamp" : 1590003971,
      "toId" : "4bgqdomQZlRIFnq9lHtKE78wyrv2",
      "tokey" : "-M7nbxCakllN4LvLsOQ0"
    },
    "-M7neJ-qsFODYXbaZeHS" : {
      "fromId" : "4bgqdomQZlRIFnq9lHtKE78wyrv2",
      "fromkey" : "-M7neJ-qsFODYXbaZeHS",
      "fulldate" : "21/05/2020",
      "message" : "hello",
      "messageseen" : "true",
      "timespot" : " 01:26 AM",
      "timestamp" : 1590004589,
      "toId" : "f4b3phpVJnTByNt2vgCKnKRuxc82",
      "tokey" : "-M7neJ-qsFODYXbaZeHT"
    }
  }
},
"f4b3phpVJnTByNt2vgCKnKRuxc82" : {
  "4bgqdomQZlRIFnq9lHtKE78wyrv2" : {
    "-M7nbxCZ3WwPGFcLRMGx" : {
      "fromId" : "f4b3phpVJnTByNt2vgCKnKRuxc82",
      "fromkey" : "-M7nbxCZ3WwPGFcLRMGx",
      "fulldate" : "21/05/2020",
      "message" : "hi",
      "messageseen" : "true",
      "timespot" : " 01:16 AM",
      "timestamp" : 1590003971,
      "toId" : "4bgqdomQZlRIFnq9lHtKE78wyrv2",
      "tokey" : "-M7nbxCakllN4LvLsOQ0"
    },
    "-M7nbxCakllN4LvLsOQ0" : {
      "messageseen" : "true"
    },
    "-M7neJ-qsFODYXbaZeHT" : {
      "fromId" : "4bgqdomQZlRIFnq9lHtKE78wyrv2",
      "fromkey" : "-M7neJ-qsFODYXbaZeHS",
      "fulldate" : "21/05/2020",
      "message" : "hello",
      "messageseen" : "true",
      "timespot" : " 01:26 AM",
      "timestamp" : 1590004589,
      "toId" : "f4b3phpVJnTByNt2vgCKnKRuxc82",
      "tokey" : "-M7neJ-qsFODYXbaZeHT"
    }
  }
}

} }

如何通过不接触旧值来避免创建额外的节点。

【问题讨论】:

    标签: firebase kotlin firebase-realtime-database android-recyclerview


    【解决方案1】:

    听起来您想在代码中获取有关在数据库中修改的数据的更详细信息。在这种情况下,您最好使用ChildEventListener 而不是ValueEventListener

    使用ChildEventListener,您可以为每个添加、更新、删除或移动的子项调用,然后您可以轻松地基于此更新 UI。例如,如果您只想将数据库中的新节点添加到列表中,您可以执行以下操作:

    toRef.addChildEventListener(object :ChildEventListener{
        override fun onCancelled(p0: DatabaseError) {
            TODO("Not yet implemented")
        }
    
        override fun onChildAdded(snapshot: DataSnapshot, previousChildKey: String) {
    
            val fromuserupdate = HashMap<String,String>()
    
            if (chatMessage.fromId != FirebaseAuth.getInstance().uid && chatMessage.toId == FirebaseAuth.getInstance().uid){
    
                val Totoken = snapshot.child("tokey").value.toString()
                val Frommessageid = snapshot.child("fromkey").value.toString()
    
                ...
    
            } 
        })
        ...
    

    【讨论】:

    • 非常感谢您的帮助。这些天我都在 ChildEventListener 中测试 ValueEventListener ,因为旧值不是新值。当我应用你的方式时,我得到了我期待的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2020-06-22
    • 2019-10-21
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多