在 iOS 上使用 Swift 多次调用 Firebase 'Observe'

Posted

技术标签:

【中文标题】在 iOS 上使用 Swift 多次调用 Firebase \'Observe\'【英文标题】:Firebase 'Observe' called multiple times with Swift on iOS在 iOS 上使用 Swift 多次调用 Firebase 'Observe' 【发布时间】:2017-04-27 22:47:57 【问题描述】:

当我在 Firebase 数据库节点上启动 observer 时,我注意到即使没有数据更改,Firebase 也会继续调用方法 observer

这是我的设置:

FIRDatabase
    .database()
    .reference(withPath: "test")
    .observe(FIRDataEventType.value, with:  (snapshot) in
            print("Firebase Data Updated");
    
);

当我对 Firebase 数据库进行 一次 更改时,observer 会多次调用其闭包函数。

Firebase 数据已更新

Firebase 数据已更新

Firebase 数据已更新

Firebase 数据已更新

Firebase 数据已更新

Firebase 数据已更新

Firebase 数据已更新

...

为什么会发生这种情况? 我怎样才能阻止这种情况的发生,并且在更新后只接到一个电话给observer

【问题讨论】:

一旦注册了监听器块,即使用户注销,它也会保持注册状态。当视图消失时,你是否分离了你的监听器? 感谢您的回复。是的,但问题是当侦听器被多次触发时,只有一次数据更新。数据更新时监听器不应该只触发一次吗? 你的代码中哪里调用了这个函数? 在 appDidLaunchWithOptions 中调用 您问题中的代码本身很好,您的想法是正确的,只要测试节点的子节点发生变化,就会调用闭包。实际上没有足够的附加代码来绘制关于正在发生的事情的上下文 - 您可能已将另一个观察者附加到节点,或者可能更改测试节点的代码格式错误。如果您可以包含更多代码,我们可能会确定它。 【参考方案1】:

这个观察者很可能被多次注册。当用户注销时,您注册的侦听器块保持注册状态,因此当用户再次登录时,您正在注册第二个侦听器。

捕获观察者的refhandle 并在完成处理后(即用户注销时)移除句柄通常是一种很好的做法。你可以这样做:

ref, handle = FIRDatabase
    .database()
    .reference(withPath: "test")
    .observe(FIRDataEventType.value, with:  (snapshot) in
            print("Firebase Data Updated");
    
);

退出时:

ref.removeObserverWithHandle(handle)

否则,确保它只被调用一次的另一种可能的解决方案是使用.observeSingleEvent() 而不是.observe()

【讨论】:

@leonardlooi 使用 .observeSingleEvent() 而不是 .observe() 并保存了我的项目。衷心感谢。!【参考方案2】:
Swift 4: 
If you want to remove all listeners registered with test node.
    Database.database().reference(withPath: "test").removeAllObservers()

If you want to remove particular listener then you need particular handler for observer. You can use following sample code.
    let ref = Database.database().reference(withPath: "test")
            let handler = ref.observe(.value)  (snapshot) in
            
            ref.removeObserver(withHandle: handler)

【讨论】:

以上是关于在 iOS 上使用 Swift 多次调用 Firebase 'Observe'的主要内容,如果未能解决你的问题,请参考以下文章

UIApplicationDidEnterBackgroundNotification 多次调用 swift 2.0

ios 8后台获取永远不会在设备上多次调用

在 obj C 项目上调用的 iOS Swift 方法

PHPhotoLibrary - photoLibraryDidChange 在 Swift 中多次调用

在 swift 3 中下载文件时,alamo fire 中的进度视图不会更新

Socket.io swift客户端自动多次重新连接