首页 > 解决方案 > Android Kotlin 等待 Firebsae 实时数据库 For-Loop 完成

问题描述

我在使用 Firebase 和 Kotlin for 循环时遇到了一些问题。

请参阅下面的场景。

这是一个示例代码

private val firebaseDB = Firebase.database.reference
private val clazzList: ArrayList<Clazz> = ArrayList()

private fun getSections() {
    val sectionList: ArrayList<Section> = ArrayList()
    for (clazz in clazzList) {
        firebaseDB.child("schools").child("sections")
            .orderByChild("classNodeKey")
            .equalTo(clazz.nodeKey)
            .addListenerForSingleValueEvent(object : ValueEventListener {
                override fun onCancelled(p0: DatabaseError) {}

                override fun onDataChange(p0: DataSnapshot) {
                    if (p0.exists()) {
                        val hashDataArray: ArrayList<HashMap<*, *>> = ArrayList()
                        for (datasnapshot in p0.children) {
                            hashDataArray.add(datasnapshot.value as java.util.HashMap<*, *>)
                        }
                        for (hashData in hashDataArray) {
                            val sectionObject = Gson().fromJson(Gson().toJsonTree(hashData), Section::class.java) as Section
                            sectionList.add(sectionObject)
                        }
                    }
                }
            })
    }
    showSections(sectionList) // Show the section list in a dialog. It is being called before the completion of for-loop above.
}

private fun showSections(sectionList: ArrayList<Section>) {
    MaterialDialog(this).show {
        title(text = "Sections")
        listItemsSingleChoice(items = sectionList)
        positiveButton(text = "OK")
    }
}

这是数据模型类Clazz.kt

data class Clazz (val nodeKey: String, val name: String)

这里一切正常,除了一件事,那就是方法 showSections(sectionList: ArrayList) 在 for 循环完成之前执行,对话框显示一个空列表

但我想先完成 for 循环,然后再显示对话框。我怎样才能做到这一点?

标签: androidfor-loopkotlinfirebase-realtime-databaseforeach

解决方案


将 showSections(sectionList) 带入 if (p0.exists()):

 private val firebaseDB = Firebase.database.reference
    private val clazzList: ArrayList<Clazz> = ArrayList()

    private fun getSections() {
        val sectionList: ArrayList<Section> = ArrayList()
        for (clazz in clazzList) {
            firebaseDB.child("schools").child("sections")
                .orderByChild("classNodeKey")
                .equalTo(clazz.nodeKey)
                .addListenerForSingleValueEvent(object : ValueEventListener {
                    override fun onCancelled(p0: DatabaseError) {}

                    override fun onDataChange(p0: DataSnapshot) {
                        if (p0.exists()) {
                            val hashDataArray: ArrayList<HashMap<*, *>> = ArrayList()
                            for (datasnapshot in p0.children) {
                                hashDataArray.add(datasnapshot.value as java.util.HashMap<*, *>)
                            }
                            for (hashData in hashDataArray) {
                                val sectionObject = Gson().fromJson(Gson().toJsonTree(hashData), Section::class.java) as Section
                                sectionList.add(sectionObject)
                            }
    showSections(sectionList) // Show the section list in a dialog. It is being called before the completion of for-loop above.
                        }
                    }
                })
        }
    }

    private fun showSections(sectionList: ArrayList<Section>) {
        MaterialDialog(this).show {
            title(text = "Sections")
            listItemsSingleChoice(items = sectionList)
            positiveButton(text = "OK")
        }
    }

推荐阅读