首页 > 解决方案 > Android Kotlin/FirebaseDatabase.addListenerForSingleValueEvent 错误..请帮帮我

问题描述

我正在为我的 kotlin 研究团队做模块化,他们不知道 firebase 的使用。当我尝试调用该函数(名为 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?
            }

模块化.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)
}

测试视图 在此处输入图像描述

错误显示 在此处输入图像描述

标签: androidkotlin

解决方案


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
        }
    })

推荐阅读