无法访问 Firebase 节点来检索应用程序的频道列表
Can't access a Firebase node to retrieve a channel list for app
我有代码应该更新列表,然后在我的 Firebase 数据库中与频道相关的所有节点都被删除后通知列表适配器,除非删除 /channellist 下的频道节点没有得到已删除,我随后的 /channellist 子监听器无法访问 ref.child("/channellist/$channelname") 下的数据。所以出于某种原因我无法访问 /channellist.
你可以看到 /channel 节点下没有 channel2,因为那个被删除了,不知道为什么 channellist 下的 channel2 没有了。
这是我的删除和列表更新功能代码:
fun deleteChannel() {
Log.d("channeltodelete", channelToDelete)
val messageKeysToDelete = ArrayList<String>()
fb.child("/channel/$channelToDelete/messages")
.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(data: DataSnapshot) {
if (!data.exists()) {
deleteChannelHelper(channelToDelete)
fb.child("/channel/$channelToDelete").removeValue()
return
}
// Deletes the messages under /message
val messagemap = data.getValue(typeindicator2)!!
for (key in messagemap) {
messageKeysToDelete.add(key.key)
}
for (key in messageKeysToDelete) {
fb.child("message/$key").removeValue()
}
// DeleteChannelHelper deletes under user/channels
deleteChannelHelper(channelToDelete)
var fb2 = FirebaseDatabase.getInstance().reference
fb.child("/channel/$channelToDelete").removeValue()
**// This is the line of code that doesn't work
fb2.child("/channellist/$channelToDelete").removeValue()**
}
override fun onCancelled(databaseError: DatabaseError) {
// report/log the error
}
}
fun processChannelListData(data: DataSnapshot) {
Log.d("channellistlistener", data.key + ": " + data.value)
val channelnames = data.children.toMutableList()
var channels = ArrayList<String>()
var channelsToDelete = ArrayList<String>()
for (channel in channelnames) {
channels.add(channel.key.toString())
}
Log.d("channelnameslistener", channels.toString())
// If a channel was added
for (channel in channels) {
if (channel !in channelList) {
channelList.add(channel)
}
}
// If a channel was deleted
for (channel in channelList) {
if (channel !in channels) {
channelsToDelete.add(channel)
}
}
channelList.removeAll(channelsToDelete)
Log.d("chanList removeall", channelList.toString())
myAdapter.notifyDataSetChanged()
}
我注意到,位于 /channellist 的 ChildEventListener 不仅在 /channellist 节点触发多次,而且对所有子节点也触发一次 由于某种原因,它弄乱了全局通道列表,因为如果访问的最后一个节点是 test1,它看起来像
2020-09-14 16:26:18.734 24448-24523/com.example.treechat D/channellistlistener: test1: -MGyjrKRLmc-wPLAjvR-
2020-09-14 16:26:18.734 24448-24523/com.example.treechat D/channelnameslistener: []
...
2020-09-14 16:26:18.734 24448-24523/com.example.treechat D/chanList removeall: []
而如果它只是顶级节点的代码就没问题
2020-09-14 16:26:18.733 24448-24520/com.example.treechat D/channellistlistener: channellist: {channel1=-MHCK1wp8mBUi_bJzxZ-, channel2=-MHDAM_k2no7ZLtUYTIU, test1=-MGyjrKRLmc-wPLAjvR-}
2020-09-14 16:26:18.733 24448-24520/com.example.treechat D/channelnameslistener: [channel1, channel2, test1]
...
2020-09-14 16:26:18.733 24448-24520/com.example.treechat D/chanList removeall: [channel1, channel2, test1]
顺便说一句,我在创建频道时访问 /channellist 没有问题,正如您所看到的,节点创建得很好。但是由于某种原因,当我这样做时应用程序崩溃了,而不是从 ChannelListActivity -> ChannelActivity,它从 ChannelListActivity -> ChannelActivity -> mini-crash -> ChannelListActivity。我会 post 在一个单独的问题中,但没有致命异常日志。
我恢复为 /channellist 使用 ValueEventListener 而不是 ChildEventListener。
我发现使用 HashMap() 并将带有 null 的路径作为我要删除的所有位置的值可以一次删除所有节点,包括频道列表中的节点。拥有 HashMap 后,您需要在数据库引用上调用 updateChildren(HashMap)。
我有代码应该更新列表,然后在我的 Firebase 数据库中与频道相关的所有节点都被删除后通知列表适配器,除非删除 /channellist 下的频道节点没有得到已删除,我随后的 /channellist 子监听器无法访问 ref.child("/channellist/$channelname") 下的数据。所以出于某种原因我无法访问 /channellist.
你可以看到 /channel 节点下没有 channel2,因为那个被删除了,不知道为什么 channellist 下的 channel2 没有了。
这是我的删除和列表更新功能代码:
fun deleteChannel() {
Log.d("channeltodelete", channelToDelete)
val messageKeysToDelete = ArrayList<String>()
fb.child("/channel/$channelToDelete/messages")
.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(data: DataSnapshot) {
if (!data.exists()) {
deleteChannelHelper(channelToDelete)
fb.child("/channel/$channelToDelete").removeValue()
return
}
// Deletes the messages under /message
val messagemap = data.getValue(typeindicator2)!!
for (key in messagemap) {
messageKeysToDelete.add(key.key)
}
for (key in messageKeysToDelete) {
fb.child("message/$key").removeValue()
}
// DeleteChannelHelper deletes under user/channels
deleteChannelHelper(channelToDelete)
var fb2 = FirebaseDatabase.getInstance().reference
fb.child("/channel/$channelToDelete").removeValue()
**// This is the line of code that doesn't work
fb2.child("/channellist/$channelToDelete").removeValue()**
}
override fun onCancelled(databaseError: DatabaseError) {
// report/log the error
}
}
fun processChannelListData(data: DataSnapshot) {
Log.d("channellistlistener", data.key + ": " + data.value)
val channelnames = data.children.toMutableList()
var channels = ArrayList<String>()
var channelsToDelete = ArrayList<String>()
for (channel in channelnames) {
channels.add(channel.key.toString())
}
Log.d("channelnameslistener", channels.toString())
// If a channel was added
for (channel in channels) {
if (channel !in channelList) {
channelList.add(channel)
}
}
// If a channel was deleted
for (channel in channelList) {
if (channel !in channels) {
channelsToDelete.add(channel)
}
}
channelList.removeAll(channelsToDelete)
Log.d("chanList removeall", channelList.toString())
myAdapter.notifyDataSetChanged()
}
我注意到,位于 /channellist 的 ChildEventListener 不仅在 /channellist 节点触发多次,而且对所有子节点也触发一次 由于某种原因,它弄乱了全局通道列表,因为如果访问的最后一个节点是 test1,它看起来像
2020-09-14 16:26:18.734 24448-24523/com.example.treechat D/channellistlistener: test1: -MGyjrKRLmc-wPLAjvR-
2020-09-14 16:26:18.734 24448-24523/com.example.treechat D/channelnameslistener: []
...
2020-09-14 16:26:18.734 24448-24523/com.example.treechat D/chanList removeall: []
而如果它只是顶级节点的代码就没问题
2020-09-14 16:26:18.733 24448-24520/com.example.treechat D/channellistlistener: channellist: {channel1=-MHCK1wp8mBUi_bJzxZ-, channel2=-MHDAM_k2no7ZLtUYTIU, test1=-MGyjrKRLmc-wPLAjvR-}
2020-09-14 16:26:18.733 24448-24520/com.example.treechat D/channelnameslistener: [channel1, channel2, test1]
...
2020-09-14 16:26:18.733 24448-24520/com.example.treechat D/chanList removeall: [channel1, channel2, test1]
顺便说一句,我在创建频道时访问 /channellist 没有问题,正如您所看到的,节点创建得很好。但是由于某种原因,当我这样做时应用程序崩溃了,而不是从 ChannelListActivity -> ChannelActivity,它从 ChannelListActivity -> ChannelActivity -> mini-crash -> ChannelListActivity。我会 post 在一个单独的问题中,但没有致命异常日志。
我恢复为 /channellist 使用 ValueEventListener 而不是 ChildEventListener。
我发现使用 HashMap