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

时间:2016-06-22 03:36:07

标签: swift firebase firebase-realtime-database

我无法在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. 有更好的方法吗?

  4. 谢谢!

3 个答案:

答案 0 :(得分:6)

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

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

如果多个用户经常更新,也可以使用事务块。

答案 1 :(得分:5)

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

答案 2 :(得分:0)

如果数据库的持久性已关闭,请遵循@Jay的回答。

但是如果您的数据库的持久性已打开,使用observeSingleEventOfType进行递增的通常方法将完全无效-它会基于旧值进行递增,并且会破坏结束。

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

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