我试图更新一个防火墙节点的事务,简单的东西。跟踪医生:
https://www.firebase.com/docs/ios/guide/saving-data.html
Firebase* upvotesRef = [[Firebase alloc] initWithUrl: @"https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes"];
[upvotesRef runTransactionBlock:^FTransactionResult *(FMutableData *currentData) {
NSNumber *value = currentData.value;
if (currentData.value == [NSNull null]) {
value = 0;
}
[currentData setValue:[NSNumber numberWithInt:(1 + [value intValue])]];
return [FTransactionResult successWithValue:currentData];
}];最大的问题是:如何检查此事务的结果(成功/失败)?我希望进行一些UI更改,取决于它的结果。
SDK文档中有另一个方法似乎有一个回调,但是它没有解释我应该检查哪个值。它说这个方法可能会被多次运行。如何确保它给出“最终”结果?https://www.firebase.com/docs/ios-api/Classes/Firebase.html#//api/name/runTransactionBlock:andCompletionBlock
对不起,我是一个初学者,苹果风格的文档真的不能在没有一些例子的情况下结合在一起。
发布于 2014-09-30 19:31:44
如果您只想等待最后的值,那么runTransactionBlock:andCompletionBlock:就是您想要查看的方法。下面是一些示例代码:
[upvotesRef runTransactionBlock:^FTransactionResult *(FMutableData *currentData) {
NSNumber *value = currentData.value;
if (currentData.value == [NSNull null]) {
value = 0;
}
[currentData setValue:[NSNumber numberWithInt:(1 + [value intValue])]];
return [FTransactionResult successWithValue:currentData];
} andCompletionBlock:^(NSError *error, BOOL committed, FDataSnapshot *snapshot) {
if (error) {
NSLog(@"Error: %@", error);
}
if (committed) {
NSLog(@"Data committed");
}
NSLog(@"Final Value: %@", snapshot.value);
}];最后一个值是snapshot.value,您可以在那里得到最后的值。如果使用FDataSnapshot,就会得到相同的observeEventType:withBlock:。
如果出了什么问题,你会得到一个error。
如果您的数据已提交,committed将为“是”。如果在事务块而不是[FTransactionResult successWithValue:]中返回[FTransactionResult successWithValue:],则committed将为否。
这意味着,如果您在4点读取计数器并尝试更新它。您可以尝试在其他人同时更新计数器。如果你先进入,snapshot.value是5,如果其他人的更新比你早,snapshot.value将是6。
不管谁先投票,你可能都想达到6岁。要做到这一点,您需要添加一个观察者。用于此的代码看起来可能如下:
[upvotesRef observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
NSLog(@"New Value: %@", snapshot.value);
}];这样,您不需要使用完成块来查找最终值,因为每次事务块发生时,观察者块都会触发。在上面的示例场景中,不管谁先投票,它都会触发一次5次,一次触发6次。如果您想知道您的特定事务是否成功,而不只是现在在该位置的值,您确实需要完成块。
而且,为了更好地完成,还有一个叫做runTransactionBlock:andCompletionBlock:withLocalEvents:的方法。如果其他人也在写入同一位置,则事务块可能会多次运行。如果发现它在陈旧的数据上运行,就会发生这种情况。当它在新数据上成功运行时,它将调用完成块。但是,您会发现,每次运行时,它都会在该位置触发任何观察者块。如果您不希望这种情况发生,则应该将否传递给withLocalEvents:。当确认的写入完成时,Firebase将触发该位置的事件,但本地事务的临时写入(未经确认)不会触发。
回顾一下你和另一个人同时试图提高选票的例子。默认情况下,一旦尝试将计数从4更新为5,观察者就会立即启动。实际事务可能会失败,因为其他人同时将向上投票数从4推到5。然后,您的事务块将使用新的数据5再次运行,并看到它应该将计数推到6。当本地事件设置为0时,观察者将在服务器让您知道其他人将向上投票数从4推到5之后,而不是在尝试将计数从4更新为5时触发。
这并不是一件简单的事情,比如每个人都在增加数据,但如果你有可能把不同的数据从其他用户那里推出来,那么在这个位置的任何观察者都可能会看到数据在最终结算之前跳来跳去。
https://stackoverflow.com/questions/26071022
复制相似问题