Firebase实时数据库单值监听器多次触发
Posted
技术标签:
【中文标题】Firebase实时数据库单值监听器多次触发【英文标题】:Firebase Realtime database single value listener triggering many times 【发布时间】:2018-08-02 15:37:13 【问题描述】:我正在尝试从其他值侦听器中的数据库接收数据。
类 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
的事件侦听器在每次reference
触发器时再调用一次方法doMyJob
,而不是每次更改只运行一次。第一次从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:抱歉代码很丑。我试图尽可能地简化问题。
【问题讨论】:
doingMyJob
到底是做什么的?
@DougStevenson 它显示了对话框,但我认为这没有任何意义。
也许您可以更新您的问题以准确解释您在此处尝试完成的工作,以及代码中的一些日志行,以及帮助我们了解实际情况的日志输出.
@Doug Stevenson 我添加了数据库结构
【参考方案1】:
您在第二个查询中使用singleEventListener
,但在您的第一个查询中,您仍在使用不会自动消失的普通事件侦听器。所以这可能是你的代码被多次调用的原因。所以问题不在于你的 single event listener 被多次调用,而是上面的那个可能是并且每次它创建一个新的 single event listener 反过来多次调用你的方法。
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)
)
)
【讨论】:
你是对的。父侦听器多次触发。不幸的是,这仍然不能解决我的问题。每次更改观察值后,父侦听器每次更改都会增量调用一次。这种方式应该有效吗? 另外,您是否尝试过为单个事件替换第一个侦听器?还是需要它来持续监控节点? 我需要它乘以,因为第一次调用返回 null。 您的第二个监听器是否更改了第一个监听器引用中的数据?这可能会导致您看到的增量效果:/ 不。doMyJob
在开始做任何事情之前被多次调用。【参考方案2】:
有趣的事情。方法 doMyJob
在显示对话框启动新片段后(抱歉在我的问题中错过了它)并且在我关闭它之后重新启动在 onActivityCreated 中添加侦听器的片段,所以... val reference
再次分配并添加了另一个侦听器。
我就是喜欢这种虫子。谢谢大家的帮助。
【讨论】:
以上是关于Firebase实时数据库单值监听器多次触发的主要内容,如果未能解决你的问题,请参考以下文章
如何实现一个 Firebase 监听器来观察数据库的实时变化
使用云功能在 Firebase 实时数据库中交换排名 - 游戏