这就是数据库在Firebase上的呈现方式
Parent
Match
User 1
Opponent : User 2
State : "NotReady"
User 2
Opponent : User 1
State : "NotReady"
我正在尝试使用RunTransaction更新State
(每个用户单独)的值。
我想做的事情:
如果他突然删除 - 中止事务(可能的情况 - 如果两个关闭事件同时运行,一个更新“状态”和其他删除所有键(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
。 有什么建议吗?谢谢!!!
答案 0 :(得分:5)
Firebase使用比较和设置方法处理交易,我将在下面介绍。它解释了为什么你得到nil
,但不幸的是意味着你当前的方法不起作用。
当您调用runTransactionBlock
时,Firebase客户端会立即调用您的块,并对该位置的当前值进行最佳猜测。这个最佳猜测可能是正确的,但如果它不知道该位置的当前值,则为nil
。
然后,Firebase客户端会发送它为您的块提供的当前值以及您返回给服务器的值。 Firebase服务器检查数据库中的当前值是否与客户端的最佳猜测相同。如果是,则写入您指定的新值。如果数据库中的值不同,则服务器拒绝新值,并将拒绝和实际当前值从数据库发送到客户端。
再次调用您的块,但这次使用关于当前值的新“最佳猜测”。
这一直持续到服务器接受操作或者尝试次数太多(我想是10或25)。