【问题标题】:Why is the currentData in my Firebase transaction always nil?为什么我的 Firebase 事务中的 currentData 总是为零?
【发布时间】:2016-04-20 15:17:46
【问题描述】:

这就是数据库在 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有什么建议吗?谢谢!!!

【问题讨论】:

    标签: ios firebase firebase-realtime-database


    【解决方案1】:

    Firebase 对事务使用比较和设置方法,我将在下面进行介绍。它解释了您收到nil 的原因,但不幸的是,这意味着您当前的方法行不通。

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

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

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

    这种情况一直持续到服务器接受操作或尝试次数过多(我认为是 10 或 25 次)。

    【讨论】:

    • 感谢您详细解释的答案。因此,如果我们将其分解,则在我正在处理的当前情况下。两个关闭事件 - 一个更新特定值,一个删除它。我应该采取什么正确的方法?如果您还记得我昨天发布的问题,使用计时器(一个删除,一个删除,所以最终结果是“迟到”的用户认为他“可以”玩,而值最终被删除)?在过去的几天里,我陷入了困境:/
    • 如果要使用事务,请在更高级别运行它,以便同时获得两个玩家的当前值。或者:使用安全规则来验证每个玩家的状态转换,从而不存在竞争条件。像这样的东西,可能是一个很好的阅读:firebase.com/blog/…
    • 我想我的架构有些问题,你能扩展一下“在更高级别上运行它”吗? +据我了解,验证和规则只能“接受或拒绝”请求,但不能操纵它们,所以如果可能的话,你所说的“替代方案”到底是什么意思。我希望不要问太多问题,我向你保证 - 这个应用程序的最终结果将是惊人的! :)
    • 我链接的文章验证了状态转换,这意味着它有效地控制了代码可以执行的转换类型。因此它无法确定代码尝试的状态转换,但它可以确保它只允许有效的转换。
    • 谢谢弗兰克。我会阅读这篇文章,如果我得出结论,我会告诉你..!
    猜你喜欢
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多