在 Firebase 中增加数据点的最简单方法?

Easiest way to increment a data point in Firebase?

我在 Firebase 中递增一段数据时遇到问题。

Firebase {
    clickedCounter: 0
}

这是我的代码:

@IBAction func plus(sender: UIButton) {
        FIRDatabase.database().reference().child("clickedCounter").observeEventType(.Value) { (snap: FIRDataSnapshot) in
            let value = FIRDatabase.database().reference().child("clickedCounter") as? NSNumber
            let increment = ((value?.intValue)! + ((1 as? NSNumber)?.intValue)!) as? NSNumber
            FIRDatabase.database().reference().child("clickedCounter").setValue()
            self.clickLabel.text = snap.value?.description as String!
        }
    }

我也试过:

@IBAction func plus(sender: UIButton) {
        FIRDatabase.database().reference().child("clickedCounter").observeEventType(.Value) { (snap: FIRDataSnapshot) in
            FIRDatabase.database().reference().child("clickedCounter").setValue((snap.value?.description)! + 1)
            self.clickedLabel.text = snap.value?.description as! String!
        }
    }

我的第一个警告是:

Cast from Int32 to NSNumber always fails

Conditional cast from NSNumber to NSNumber always succeeds

Cast from FIRDatabaseReference to NSNumber always fails

在我 运行 它之后,我在 let increment.... 上得到了错误:Thread 1: EXC_BAD_INSTRUCTION

我的第二个错误是:

Binary operator + cannot be applied to operands of the type String and Int

  1. 当我以为我在 Firebase 中将它定义为 Int 时,我很困惑我的 snap.value?.description 是一个字符串。

  2. 为什么总是成功时我会收到警告?

  3. 有更好的方法吗?

谢谢!

尝试使用事务来安全地获取当前数据并递增它。 请参阅此处文档中的示例: https://firebase.google.com/docs/database/ios/save-data#receive_a_completion_callback

为什么不呢(v2.x Firebase 代码,但你明白了)

counterRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
     let valString = snapshot.value
     var value = valString.intValue
     value = value + 1
     counterRef.setValue("\(value)")         
})

如果这将被多个用户频繁更新,也可以利用交易块。

如果数据库已关闭持久性,请按照@Jay 的回答进行操作。

但是如果你的数据库开启了持久化,用observeSingleEventOfType递增的常用方法根本行不通——它会根据旧值递增,到最后会一团糟

幸运的是,由于 Natural Lam 在他的文章 here 中描述的发现,在持久性打开的情况下,仍然有一种方法可以可靠地增加。诀窍在于强制 Firebase 通过 keepSynced 和写入操作的组合来同步数据。这是一个对我有用的例子:

func increaseUnreadChatsFor(chatId: String) {
    let chatRef = self.ref.child("chats/\(chatId)")
    chatRef.keepSynced(true)
    chatRef.child("dummy").setValue("dummy") { _, _ in
        chatRef.child("dummy").removeValue()
        chatRef.keepSynced(false)
        chatRef.child("unread").observeSingleEvent(of: .value, with: { snapshot in
             if !snapshot.exists() { // no unread record yet, creating one
                chatRef.child("unread").setValue(1)
             } else if let unread = snapshot.value as? Int { // record already exists, incrementing it
                chatRef.child("unread").setValue(unread + 1)
             }
         })
    }
}

当然不能保证离线工作。

另一种选择是再次配置相同的数据库,但这次关闭持久性并使用该 firebase 实例进行增量(这显然只能在线工作)。如何做到这一点,您可以在我的回答中阅读 here