#android #firebase #kotlin #firebase-realtime-database #persistence
#Android #firebase #kotlin #firebase-база данных в реальном времени #постоянство
Вопрос:
У меня есть код, который должен обновить список, а затем отправить notifyDataSetChanged() в адаптер списка после удаления всех узлов, связанных с каналом в моей базе данных Firebase, за исключением того, что после удаления узла канала в / channellist не удаляется, и мой последующий дочерний прослушиватель для / channellist не может получить доступ к данным в разделе ref.child(«/ channellist/$ channelname»). Поэтому по какой-то причине я не могу получить доступ к / channellist.
Вы можете видеть, что под узлом / channel нет channel2, потому что он был удален, и по какой-то причине 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()
}
Я замечаю, что ChildEventListener, который размещен в / channellist , запускается несколько раз не только на узле / 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 -> мини-сбой -> ChannelListActivity. Я опубликую это в отдельном вопросе, но журналов фатальных исключений нет.
Ответ №1:
Я вернулся к использованию ValueEventListener для / channellist вместо ChildEventListener.
Я обнаружил, что использование HashMap<String, Any?>() и указание пути с null в качестве значения для всех местоположений, которые я хотел удалить, помогло удалить все узлы сразу, в том числе в списке каналов. Как только у вас будет HashMap, вам нужно вызвать updateChildren (HashMap) для ссылки на базу данных.