我在我的应用中使用了Firebase's Realtime database.我正在从数据库中获取数据,并进行了一些更改,之后我就是removing the observer岁,这不是很好.

我在Realtime Database中有一些数据是这样的:

firebase data

我使用了Firebase的Obview(.value)函数来获取这个值,然后我更新了一个条目,然后删除了观察者.这是我的代码:

func updatePoints() {
        
        let firebaseId = UserDefaults.standard.value(forKey: "firebaseId") as? String ?? ""
        
        let reference = self.database.child("Points").child(firebaseId)
        var handler : UInt = 0
        
        handler = reference.observe(.value, with: { snapshot in
            
            guard let userPoints = snapshot.value as? [String : Any] else {
                print("no points data found")
                return
            }
            

            let pointsLeft = userPoints["points_left"] as? Int ?? 0
            
            reference.child("points_left").setValue(pointsLeft - 1)

            reference.removeObserver(withHandle: handler)
        })
    }

现在的问题是,这个观察者跑了两次.例如,如果为"points_left" : 10,则在此函数之后,剩余的点数将具有8个值,但它应该为9.它运行了两次,我不明白为什么它会在我使用removeObserver的时候这样做.有没有人能帮我一下?

推荐答案

出现上述意外行为的原因是您为更新点而调用的setValue函数正在触发数据库中的另一个.value事件.然后,它再次触发观察者.因此,当您移除观察者时,它已经触发了两次.这导致点数减少2而不是1.

所以如果你互换了最后两行,那么当你调用setValue函数的时候,观察器就被移除了.所以它不会第二次被触发.

Swift相关问答推荐

计算Vision OS相机与Vision OS中3D模型之间的距离

SwiftUI map 旋转

SWIFT`String.Encoding`:`.unicode`vs`.utf16`

物理主体未与 spritekit Swift 的网格图案上的纹理图像对齐

使用View()和List()无法显示影子

在这个使用 URLSession 的简单 case 中是否创建了一个强引用循环?

iOS16 Bug 键盘在表单解雇 SwiftUI 时打破布局

使用列表的下一项更新相同的视图

类型 '()' 不能符合 View (除非它肯定是 View,这次没有恶作剧)

将阻塞函数集成到 Swift 异步中

SwiftUI:从存储在 observableObject 中的数组中删除对象时查看崩溃

如何在 RxSwift 中获取 controlEvent 类型?

我如何从 UIAlertController 导航到新屏幕(swiftUI)

如何仅将 SwiftUI 不透明度应用于父视图?

Swift 2 中的新 @convention(c):我该如何使用它?

如何在 Swift 中将对象归零

在 Swift 框架中加载资源(例如故事板)

Swift 中的 CommonHMAC

在 Swift 中为 UIPickerView 设置默认值?

在情节提要中设置的 UITableViewCell 的恢复 ID 和标识符有什么区别