Как получить данные из Firebase Database?
Есть функция:
fun DatabaseReference.takeAll(): Any {
this.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()) {
val counter = snapshot.childrenCount
if (counter > 1) {
val list: MutableList<String>? = null
for (i in snapshot.children) {
list?.add(i.key.toString())
}
} else if (counter == 1L) {
val data = snapshot.value.toString()
}
} else {
Log.e(TAG, "Take All Function: snapshot is not exist")
}
}
override fun onCancelled(error: DatabaseError) {
Log.e(TAG, error.message)
}
})
}
Её задача — достать данные из БД по определенному пути и вернуть мне их.
У меня несколько вопросов:
Что писать как возвращаемое значение, т. к. оно может быть и списком и просто строкой.
Как в конце функции вернуть значение только когда данные полностью загрузятся, чтобы после вызова я их записал и пошел дальше работать.
Пробовал вернуть в for или в else if, но ругается на то, что функция onDataChange должна возвращать Unit. При попытке вернуть не Unit ругается на override, что предсказуемо.
Запускается функция из main-потока, но можно реализовать её как корутину. Вызывать я планирую её примерно вот так:
val data = путь.takeAll()
И дальше какие то действия с ней.
Ответы (1 шт):
По документации Firebase, чтобы единоразово вытащить данные из базы, нужно выполнить следующий код:
database.child("users").child(userId).get()
.addOnSuccessListener { data ->
println("Пользователь: ${data.value}")
}
.addOnFailureListener { exception ->
println("Не удалось получить пользователя из базы")
exception.printStackTrace()
}
Для удобной интеграции Tasks API с корутинами есть расширение kotlinx-coroutines-play-services. Экстеншен await() упростит работу с отложенными Task. Тот же самый код будет выглядеть так:
try {
val data = database.child("users").child(userId).get().await()
println("Пользователь: ${data.value}")
} catch (exception: Exception) {
println("Не удалось получить пользователя из базы")
exception.printStackTrace()
}
Экстеншен await() является suspend-функцией, поэтому может быть вызван только из другой suspend-функции либо из корутины.