在 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
当我以为我在 Firebase 中将它定义为 Int 时,我很困惑我的 snap.value?.description
是一个字符串。
为什么总是成功时我会收到警告?
有更好的方法吗?
谢谢!
尝试使用事务来安全地获取当前数据并递增它。
请参阅此处文档中的示例:
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。
我在 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
当我以为我在 Firebase 中将它定义为 Int 时,我很困惑我的
snap.value?.description
是一个字符串。为什么总是成功时我会收到警告?
有更好的方法吗?
谢谢!
尝试使用事务来安全地获取当前数据并递增它。 请参阅此处文档中的示例: 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。