Не удается получить доступ к узлу Firebase для получения списка каналов для приложения

#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) для ссылки на базу данных.