Я новичок в Android и Kotlin, и я хочу реализовать в своем проекте класс FirebaseRetriever, который возвращает конкретный моментальный снимок базы данных.
Теперь у меня возникают проблемы с тем, что EventListener никогда не запускается, и поэтому, конечно же, я возвращаю нулевой объект.
Вот мой класс данных:
public class FirebaseRetriever() {
private val TAG = "FirebaseRetriever"
private lateinit var fbData: FirebaseDatabase
private lateinit var fbAuth: FirebaseAuth
private lateinit var userRef: DatabaseReference
//Snapshots
private lateinit var userSnap: DataSnapshot
init {
fbData = FirebaseDatabase.getInstance()
userRef = fbData.reference.child("users")
fbAuth = FirebaseAuth.getInstance()
userRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(e: DatabaseError) {
Log.e(TAG, "Data could not be retrieved from Database." + e.message)
}
override fun onDataChange(snap: DataSnapshot) { // is never executed
userSnap = snap
}
})
}
public fun getUserSnap(): DataSnapshot {
return userSnap // returns null
}
}
Вот как я вызываю getUser ():
firebaseRetriever = FirebaseRetriever()
...
val uniSnap = firebaseRetriever.getUniSnap()
Возможно ли, что Firebase EventListener может работать только в обычном AndroidActivity, или я делаю что-то еще не так?
Заранее спасибо.
Скорее всего, данные просто еще не были загружены, когда вы вызываете getUserSnap. Чтобы убедиться в этом, добавьте еще несколько операторов журнала:
Log.i(TAG, "Starting to read from database.")
userRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(e: DatabaseError) {
Log.e(TAG, "Data could not be retrieved from Database." + e.message)
}
override fun onDataChange(snap: DataSnapshot) { // is never executed
Log.i(TAG, "User read from database.")
userSnap = snap
}
})
public fun getUserSnap(): DataSnapshot {
Log.i(TAG, "Getting user.")
return userSnap // returns null
}
Когда вы запустите свое приложение с этим, результат, скорее всего, будет следующим:
Starting to read from database.
Getting user.
User read from database.
Вероятно, это не тот порядок, которого вы ожидали. Firebase загружает данные из базы данных асинхронно, поскольку для получения результатов может потребоваться некоторое время. Вместо того, чтобы заставлять ваше приложение ждать (что вызовет диалоговое окно «Приложение не отвечает»), вашему коду разрешено продолжить. Но когда вы вызываете getUserSnap, этот пользователь еще не загружен.
Самое простое решение - переместить весь код, требующий доступа к пользователю в, методом onDataChange(). Также см. Мой ответ на этот вопрос о более гибком решении, требующем большего количества кода: Метод getContactsFromFirebase () возвращает пустой список