【问题标题】:Firebase observer not working, why won't it keep a watch on the value change?Firebase 观察者不工作,为什么不关注价值变化?
【发布时间】:2019-05-23 22:47:55
【问题描述】:

我正在尝试通过调用以下命令来设置 Firebase 观察者:

ref.child(id).child("isLocked").observe(.value, with: { snapshot in

    print("isLocked = ", snapshot.value!)

})

当视图加载时,它可以完美运行。它打印出正确的值。

当我在 Firebase 本身或单独的设备上更改值时,isLocked 将不再打印。应该是什么时候,因为我在路上有一个观察者。什么给了?

这里的最终目标是根据 lock 值是 true 还是 false 来提供 UIButton。

视图加载了button.isHidden = true

更新

我发现观察者问题的根源不是“工作”

似乎存在时间问题。

在之前的视图控制器(进入新的视图控制器)中,我在“viewDidDisappear”函数中调用ref.child(pID).child("isLocked").removeAllObservers()

在新的视图控制器中,我正在“尝试”设置相同的路径观察者 'ref.child(id).child("isLocked").observe(.value, with: { snapshot in'

我猜removeAllObservers() 胜过新观察者的设置!?我该如何克服这个!?

【问题讨论】:

  • 您能否包含显示您如何更改其他设备上的数据库的最少代码?
  • @FrankvanPuffelen 我将直接进入 Firebase 并将锁定值从 true 更改为 false,反之亦然,没有任何反应。
  • @FrankvanPuffelen 我还添加了更多细节,以通过 lock 值切换为 true 或 false 来实现
  • 这很不常见。您确定要更改正确 ID 下的 isLocked 吗?另请注意,既然您说“或在单独的设备上”,我假设您也可以更改代码,这样更容易看到发生了什么。
  • @FrankvanPuffelen 是的...如果我将观察者放在“.childChanged”上,它确实有效!?但同样它只是在改变......我不知道为什么它不会接受 .value!?

标签: swift firebase firebase-realtime-database observers


【解决方案1】:

我发现观察者问题的根源不是“工作”

似乎有时间问题。

在之前的视图控制器(进入新的视图控制器)中,我在 viewDidDisappear 函数中调用 ref.child(pID).child("isLocked").removeAllObservers()

在新的视图控制器中,我正在“尝试”设置相同的“路径观察者”ref.child(id).child("isLocked").observe(.value, with: { snapshot in

我猜removeAllObservers() 胜过新观察者的设置!?

要解决这个问题,您需要为每个观察者设置特定的句柄!确保使用唯一的 var 名称并且不重复使用,然后调用以下代码而不是 removeAllObservers()

ref.child(id).child("isLocked").removeObserver(withHandle: confirmVCRefHandle!)

上面的句柄名称confirmVCRefHandle是唯一的,时间问题已经解决了!

【讨论】:

  • “我猜 removeAllObservers() 胜过新观察者的设置!?”不,这似乎不太可能。这两个调用不相关,Firebase 不知道您应用中的视图。更有可能是您的 removeAllObservers() 调用发生在您在新视图中注册观察者之后,因此该观察者立即被删除。
  • @FrankvanPuffelen 我同意,因此我说这是一个“时间”问题。但正如我在“回复”中所写,需要确保您使用唯一的句柄,因为您也说过,viewDidDisappear 和新的视图控制器运行。我希望您会发现 viewDidDisappear 最后触发(因为新视图需要在旧视图消失之前显示),因此对 removeAllObservers 的调用发生在将侦听器附加到新视图中之后。
【解决方案2】:

试试这个:

ref.child(id).observe(.childChanged, with: { snapshot in

    if snapshot.key == "isLocked" {
        if let value = snapshot.value as? Bool {
            print(value)
        }
    }
})

【讨论】:

  • 观察.childchanged 直到值改变至少一次之后才会启动监听器。所以它不适用于我的用例。
  • 另外我直接更改了 Firebase 中的值,观察者没有监听更改。
  • 是的。在我的项目中,我同时使用 .childChanged 和 .childAdded。并且 .childRemoved 了。我相信只有 .childAdded 在启动时加载所有值,然后只添加添加的项目。
  • .value 将减少您的代码,并且不需要 .childAdded、.childChanged 并且在实例中有 .childRemoved
猜你喜欢
  • 2015-09-05
  • 1970-01-01
  • 2019-10-12
  • 2014-03-24
  • 1970-01-01
  • 2011-04-14
  • 2013-01-30
  • 2017-12-04
  • 1970-01-01
相关资源
最近更新 更多