首页 > 解决方案 > 如何避免拾取已经存在的数据库节点--Recyclerview Items

问题描述

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

我的聊天工作流程是:

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

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

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

在发送消息时,还有另一个函数将通过识别 ChatFromItem 适配器和 ChatToItem 适配器来接收来自两端的消息。

在 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"
    }
  }
}

} }

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

标签: firebasekotlinfirebase-realtime-databaseandroid-recyclerview

解决方案


听起来您想在代码中获取有关在数据库中修改的数据的更详细信息。在这种情况下,您最好使用 aChildEventListener而不是 a 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()

            ...

        } 
    })
    ...

推荐阅读