Android Kotlin / FirebaseDatabase.addListenerForSingleValueEvent错误..请帮助我

时间:2019-11-23 02:41:49

标签: android kotlin

我正在为不了解Firebase使用情况的Kotlin研究团队进行模块化。当我尝试调用名为getEyeSavingData的函数时,发生了一些问题...请帮助...

调用函数为A.kt的位置

    isgTestButton.setOnClickListener {
                val database = FirebaseDatabase.getInstance()
                val eDB = database.getReference("eyesaving")

                //eDB.child("food").child("test").setValue(EyeSavingData("name", "element", "effect", 1234, "explain"))
                setEyeSavingData(Category.food, "orange", EyeSavingData("orange", "Vitamin C", "good at Eye", 1000, "Orange is Orange"))
                //set Data has good work


                val dTestVal = getEyeSavingData(Category.food, "orange")
                if(dTestVal != null)
                    isgTestTextView.text = dTestVal.name + dTestVal.element //Error?
            }

Modulization.kt

data class EyeSavingData(
    var name: String?,
    var element: String?,
    var effect: String?,
    var cost: Int?,
    var explain: String?
)

enum class Category {
    food, tea
}

/*
 *  함수명 : getEyeSavingData (카테고리(food, tea 등), 카테고리 내 음식 이름)
 *  반환값 : EyeSavingData 또는 null
 *  설명 : name 파라미터를 넣지 않고 호출할 경우 카테고리 내 전체 데이터를 EyeSavingData class 형태로 반환하고,
 *         name 파라미터에 값을 넣을 경우 카테고리 내 해당 이름의 데이터를 EyeSavingData 형태로 반환합니다.
 *  Tips : getEyeSavingData 를 호출할 때 파라미터는 Category.food, Category.tea 등을 사용하면 편리합니다.
 *  사용예시 : getEyeSavingData(Category.food, "orange")   // food 카테고리 내 orange 음식의 데이터를 반환합니다.
 */
public fun getEyeSavingData(categoryEnum: Category, name: String) : EyeSavingData? {
    var category: String?
    when(categoryEnum){
        Category.food -> category = "food"
        Category.tea -> category = "tea"
    }
    var userData = FirebaseDatabase.getInstance().getReference("eyesaving")
    var retData: EyeSavingData? = null

    val eData = userData.child(category).addListenerForSingleValueEvent(object: ValueEventListener{
        override fun onCancelled(p0: DatabaseError) {}
        override fun onDataChange(p0: DataSnapshot) {
            var eDataString = p0.getValue() as Map<String, EyeSavingData?>
            retData = eDataString.get(name) //i assume happening error is here
        }
    })
    return retData
}

public fun setEyeSavingData(categoryEnum: Category, name: String, data: EyeSavingData){
    val database = FirebaseDatabase.getInstance().getReference("eyesaving")
    var category: String?
    when(categoryEnum){
        Category.food -> category = "food"
        Category.tea -> category = "tea"
    }
    database.child(category).child(name).setValue(data)
}

测试视图 enter image description here

错误显示 enter image description here

1 个答案:

答案 0 :(得分:0)

您的getEyeSavingData将始终返回null,因为addListenerForSingleValueEvent是异步的。

因此,如果您想使用此次通话中的数据,可以像这样在onDataChange内获取数据-

 val eData = userData.child(category).addListenerForSingleValueEvent(object: ValueEventListener{
        override fun onCancelled(p0: DatabaseError) {}
        override fun onDataChange(p0: DataSnapshot) {
            var eDataString = p0.getValue() as Map<String, EyeSavingData?>
            retData = eDataString.get(name) 
            //Here you can use retData
            if(dTestVal != null)
                isgTestTextView.text = dTestVal.name + dTestVal.element
        }
    })