为了账号安全,请及时绑定邮箱和手机立即绑定

代码不等待 FirebaseDatabase 被读取

代码不等待 FirebaseDatabase 被读取

慕尼黑的夜晚无繁华 2021-05-31 08:35:56
所以我有这个使用 Firebase 的应用程序。问题是它需要一些输入(假设 X),从 FirebaseDatabase 读取一些数据(假设 Y),然后比较它们。如果 Y 的某些元素与 X 的相应元素匹配,则认为它们是重复的并且仅更新 Y 的值。如果两者的元素不匹配,那么它会在数据库中创建一个带有 X 的新条目。现在,我的代码有一个按钮,它调用 checkDataNew() 方法来检查上述值的相似性。它负责从数据库中读取数据,然后将其与输入值进行比较。然后使用该函数的结果更新/添加 FirebaseDB 中的值。如果我保持活动打开,然后输入类似的值,它会完美运行,并且只会更新 FirebaseDB 中的值。但是,如果我关闭活动然后再次打开它,则它不会进入 addValueEventListener 函数来从 FirebaseDB 读取数据。我知道,因为我已经调试过了。在第一个场景中,代码转到 rootRef.addValueEventListener 代码中写入的行,但在第二个场景中,它没有。不用说,这会导致我的应用程序中出现重复项的问题。任何人都可以解释为什么 addValueEventListener 代码在活动打开并多次提供输入时执行,但如果我关闭活动并重新打开它却无法执行?相关代码写在下面(它在 Kotlin 中,但即使有人有 Java 的解决方案,我也可以将其转换为 Kotlin):checkInsulinBtn?.setOnClickListener(){        var isDataValidCheck:Boolean=validateData()        if(isDataValidCheck==true)        {            checkDataNew() //calls Firebase DB read function            var newKey=foundKey            if(newKey=="")            {                var mLogBG:BGLevel= BGLevel(emailID,recentFood,recentEvent,BGLevel,insulinLevel,calendarTime)                var key:String=mFirebaseDatabaseReference.push().toString()                var parsedKeyList=key.split("/-")                var parsedKey=parsedKeyList[1]                parsedKey="-" + parsedKey                mFirebaseDatabaseReference.child(parsedKey).setValue(mLogBG)                var mFirebaseDatabaseReference2=mFirebaseDatabase.getReference("BG Keys")                mFirebaseDatabaseReference2.push().setValue(parsedKey)                Toast.makeText(applicationContext,"Your data has been saved to the cloud, and is viewable in the app calendar",Toast.LENGTH_SHORT).show()            }            else            {                var mLogBG:BGLevel= BGLevel(emailID,recentFood,recentEvent,BGLevel,insulinLevel,calendarTime)                var newKey=foundKey                mFirebaseDatabaseReference.child(foundKey).setValue(mLogBG)                Toast.makeText(applicationContext,"Your previous data has been updated with the new one",Toast.LENGTH_LONG).show()            }        }}
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

正如 Selvin 评论的那样:数据是从 Firebase 异步加载的。您无法可靠地等待数据可用。请参阅在 Firebase Listener 中设置 Singleton 属性值。


该解决方案是移动从火力地堡数据需要的代码到所述onDataChange中checkDataNew:


fun checkDataNew() {

    var rootRef=FirebaseDatabase.getInstance().getReference("BG Data")

    // Read from the database

    rootRef.addValueEventListener(object : ValueEventListener {

        override fun onDataChange(dataSnapshot: DataSnapshot) {

            var isKeyFound = false; // local variables

            var foundKey;

            // This method is called once with the initial value and again

            // whenever data at this location is updated.

            for(data:DataSnapshot in dataSnapshot.children)

            {

                var oldEvent=data.child("recentEvent").getValue().toString()

                var oldDate:String=data.child("calendarTime").getValue().toString()

                var oldEmailID:String=data.child("emailID").getValue().toString()


                if(oldEvent.equals(recentEvent) && oldDate.equals(calendarTime) && oldEmailID.equals(emailID)) {

                    foundKey = data.key.toString()

                    isKeyFound = true

                }

            }


            // TODO: process the result here

            if (isKeyFound) {

              ...

            } else {

              ...

            }

        }


        override fun onCancelled(error: DatabaseError) {

            // Failed to read value

        }

    })

}

或者,您可以定义自己的回调接口,将其传入checkDataNew并从那里调用它。有关此示例,请参阅getContactsFromFirebase() 方法返回空列表。


查看完整回答
反对 回复 2021-06-02
  • 1 回答
  • 0 关注
  • 152 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信