firebase - 如何避免拾取已经存在的数据库节点--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"
}
}
}
} }
如何通过不接触旧值来避免创建额外的节点。
解决方案
听起来您想在代码中获取有关在数据库中修改的数据的更详细信息。在这种情况下,您最好使用 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()
...
}
})
...
推荐阅读
- python - 为什么这段代码会产生这样的输出而不是这样的输出?
- sql - 在 sql 语句上收到 Null
- javascript - 当父级“选择”类时如何更改图像 src?
- javascript - 标识符后跟冒号
- c++ - 在 C++ 中,是否有任何理由生成并立即加入线程,而不是直接调用函数?
- java - 如何对已转换为整数类型的字段 LocalTime 类型执行范围查询
- reactjs - 无法在 handleOnSuccess 方法上设置状态-react-plaid-link 集成
- python - 目前使用Android qpython。如何发出类似于 winsound.Beep 的哔声?
- javascript - 如何使用我的网络应用程序中的 JavaScript 将 JSON 字符串写入和读取到 Google Cloud 存储桶?
- spss - 如何在 SPSS 中使用来自其他受访者的数据计算新变量?