Firebase实时数据库单值侦听器触发多次

时间:2018-02-22 17:05:57

标签: android firebase firebase-realtime-database kotlin

我试图从其他值监听器中的数据库接收数据。

class MyFragment:Fragment(){

private lateinit var reference: DatabaseReference

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    reference = FirebaseDatabase.getInstance().reference.child("FIRST_ROOT")
            .child("FIRST_CHILD")
            .child("CHILD_1")
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    reference.addValueEventListener(object : EventListener() {
        override fun onDataChange(p0: DataSnapshot?) {
            val childOfSecondRoot= p0?.value
            FirebaseDatabase.getInstance().reference.child("SECOND_ROOT")
                      .child(childOfSecondRoot).addListenerForSingleValueEvent(object : EventListener() {
                          override fun onDataChange(p0: DataSnapshot?) {
                             doingMyJob(p0?.value)
                    }
            })
        }
    })
}

我的目标是每次更改参考值中的观察值时运行方法doingMyJob

由于某种原因,事件监听器添加为addListenerForSingleValueEvent,每次doMyJob触发时再次调用方法reference,而不是每次更改只运行一次。首先从reference读取即可,但第二次调用doMyJob 2次,第三次调用3次,依此类推。重新启动应用程序历史记录从开始。方法doMyJob()不会更改数据库中的任何值。

现在我知道,对于每个观察值的单一变化,父侦听器被称为增量。

数据库结构:

|MAIN_ROOT |\FIRST_ROOT | \FIRST_CHILD | |DATA_TO_RECEIVED //reference field - parent listener for many events |\SECOND_ROOT | \DATA_TO_RECEIVED // root name received in nested listener-as single value | |CHILD_1 | |CHILD_2 | |CHILD_3

我做错了吗?是否有可能从侦听器运行侦听器,从而避免对嵌套侦听器进行增量调用?

PS:对不起代码很抱歉。我试图尽可能简单地解决问题。

2 个答案:

答案 0 :(得分:2)

您在第二次查询中使用了singleEventListener,但在您的第一次查询中,您仍然使用不会自动消失的普通事件监听器。这可能是您的代码被多次调用的原因。所以问题不在于您多次调用单个事件监听器,但上面的那个可能是,并且每次创建新的单个事件监听器时反过来多次调用你的方法。

reference.addValueEventListener(object : EventListener() { //ordinary event listener will be kept running 
        override fun onDataChange(p0: DataSnapshot?) {
            val childOfSecondRoot= p0?.value
            FirebaseDatabase.getInstance().reference.child("SECOND_ROOT")
                      .child(childOfSecondRoot).addListenerForSingleValueEvent(object : EventListener() {
                          override fun onDataChange(p0: DataSnapshot?) {
                             doingMyJob(p0?.value)
                    }
            })
        }
    })

答案 1 :(得分:1)

有趣的是。在显示对话框启动新片段之后的方法doMyJob(抱歉在我的问题中错过了它)并且在我关闭它之后在onActivityCreated中添加监听器的片段被重新启动以便...再次分配val reference和另一个监听器已添加。

我只是喜欢这种错误。谢谢大家的帮助。

相关问题