Как правильно использовать Firebase Database ChildEventListener с ViewModel? - PullRequest
1 голос
/ 01 августа 2020

В Android ОС из-за различных изменений конфигурации, таких как изменение ориентации, действие уничтожается и создается заново. Но это также приводит к увеличению затрат, таких как повторная выборка данных для отображения пользовательского интерфейса. Таким образом, ViewModel был разработан для хранения данных до тех пор, пока действие не будет действительно уничтожено, что обеспечивает безопасность во время изменений конфигурации.

Я использую базу данных Firebase Realtime в своем приложении, и я очень хорошо знаком с ChildEventListener присутствует в SDK Firebase. Поскольку использование ViewModel дает так много преимуществ, мне интересно использовать его в своем приложении. Я читал различные источники, блоги, касающиеся архитектуры ViewModel вместе с Firebase: но они используют только прослушиватели ValueEvent. Я показываю RecyclerView в приложении, и ChildEventListener - идеальный кандидат для этого.

Я хочу вести список, используя ChildEventListener с архитектурой ViewModel. Я написал код для активного извлечения данных, используя ViewModel.

class DataViewModel : ViewModel() {

    private var listenerRemovePending = false
    private val listener = MyChildEventListener()
    private val handler = Handler(Looper.getMainLooper())
    private lateinit var dataListRef: DatabaseReference

    var data: MutableLiveData<ArrayList<DataModel>> = MutableLiveData()
    val dataList: ArrayList<DataModel> = arrayListOf()

    fun getData(userId: String): LiveData<ArrayList<DataModel>> {
        dataListRef =
            FirebaseDatabase.getInstance().getReference("/data/$userId/data")
        dataListRef.addChildEventListener(object : ChildEventListener {
            override fun onCancelled(databaseError: DatabaseError) {
                Log.e(
                    LOG_TAG,
                    "Can't listen to query :dataListRef",
                    databaseError.toException()
                )
            }

            override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
                TODO("Not yet implemented")
            }

            override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
                TODO("Not yet implemented")
            }

            override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
                if (snapshot.exists()) {
                    val item: DataModel? =
                        snapshot.getValue(DataModel::class.java)
                    if (item != null) {
                        dataList.add(item)
                    }
                    data.value = dataList
                }
            }

            override fun onChildRemoved(snapshot: DataSnapshot) {
                TODO("Not yet implemented")
            }
        })
        return data
    }

    companion object {
        private const val LOG_TAG = "DataViewModel"
    }
}

Я доволен его результатом. Но вот основная проблема - я хочу, чтобы этот ChildEventListener отключался, если нет наблюдателя (Activity не активен). В настоящее время этот слушатель активен, пока действие не закончится - этот ViewModel будет держать свой слушатель прикрепленным до тех пор, пока не будет вызван метод Activity onDestroy.

Итак, мой вопрос в том, как я могу отсюда отсоединить слушателя в неактивном состоянии?

...