Android 活动外部的Firebase数据库EventListener

Android 活动外部的Firebase数据库EventListener,android,firebase,firebase-realtime-database,kotlin,Android,Firebase,Firebase Realtime Database,Kotlin,我是Android和Kotlin的新手,我想在我的项目中实现一个FirebaseRetriever类,该类返回一个特定的数据库快照 现在我遇到了EventListener从未被触发的问题,因此,当然,我得到了一个null对象 这是我的数据类: public class FirebaseRetriever() { private val TAG = "FirebaseRetriever" private lateinit var fbData: FirebaseDatabase

我是Android和Kotlin的新手,我想在我的项目中实现一个FirebaseRetriever类,该类返回一个特定的数据库快照

现在我遇到了EventListener从未被触发的问题,因此,当然,我得到了一个null对象

这是我的数据类:

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()的方式:

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
}
当您使用此选项运行应用程序时,输出可能是:

开始从数据库中读取

正在获取用户

用户从数据库中读取

这可能不是您期望的顺序。Firebase从数据库异步加载数据,因为可能需要一些时间才能获得结果。您的代码可以继续,而不是让应用程序等待(这会触发应用程序无响应对话框)。但是当您调用
getUserSnap
时,该用户尚未加载

最简单的解决方案是将用户需要访问的所有代码移动到
onDataChange()
方法中。另请参见我对这个问题的回答,了解更灵活的解决方案,它需要更多的代码:

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
}