为什么我的Firebase事务中的currentData总是为零?

时间:2016-01-15 03:53:10

标签: ios firebase firebase-realtime-database

这就是数据库在Firebase上的呈现方式

Parent
      Match
           User 1
                 Opponent : User 2
                 State    : "NotReady"
           User 2 
                 Opponent : User 1
                 State    : "NotReady"

我正在尝试使用RunTransaction更新State(每个用户单独)的值。

我想做的事情:

  • 检查项目是否已删除(不是nil / null)
  • 如果他存在 - 更新值
  • 如果他不存在 - 操纵UI
  • 如果他突然删除 - 中止事务(可能的情况 - 如果两个关闭事件同时运行,一个更新“状态”和其他删除所有键(removeValue)

     let path =  "Parent/Match/User 1/state"
    
     let futureRef = Firebase(url: path)
             futureRef.runTransactionBlock({
        (currentData:FMutableData!) in
        let value = currentData.value as? String
    
        if value != nil  {
            currentData.value = "Ready"
    
            return FTransactionResult.successWithValue(currentData)
        }
    
            return FTransactionResult.abort()
    
        }, andCompletionBlock: {
            // Completion Check
            (error:NSError!, success:Bool, data:FDataSnapshot!) in
    
            if error == nil && success && data.value as! String == "Ready"
            {
                //Value is not null(not removed) and he is ready
                  ManipulateUI()
    
            }
            else 
          {
    
            //Value deleted
           }
    
    
            }
        )
    

但出于某种原因 - 我正在获得nil的currentData并直接进入Abort有什么建议吗?谢谢!!!

1 个答案:

答案 0 :(得分:5)

Firebase使用比较和设置方法处理交易,我将在下面介绍。它解释了为什么你得到nil,但不幸的是意味着你当前的方法不起作用。

当您调用runTransactionBlock时,Firebase客户端会立即调用您的块,并对该位置的当前值进行最佳猜测。这个最佳猜测可能是正确的,但如果它不知道该位置的当前值,则为nil

然后,Firebase客户端会发送它为您的块提供的当前值以及您返回给服务器的值。 Firebase服务器检查数据库中的当前值是否与客户端的最佳猜测相同。如果是,则写入您指定的新值。如果数据库中的值不同,则服务器拒绝新值,并将拒绝和实际当前值从数据库发送到客户端。

再次调用您的块,但这次使用关于当前值的新“最佳猜测”。

这一直持续到服务器接受操作或者尝试次数太多(我想是10或25)。