Firebase如何检查交易成功或失败?

Posted

技术标签:

【中文标题】Firebase如何检查交易成功或失败?【英文标题】:Firebase how to check transaction success or fail? 【发布时间】:2014-09-27 03:30:51 【问题描述】:

我正在尝试更新事务中的 firebase 节点,简单的东西。跟随文档:

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:

对不起,我是一个初学者,如果没有一些示例,Apple 风格的文档真的无法组合在一起。

【问题讨论】:

【参考方案1】:

如果您只是想等待最终值,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 是您可以获得最终值的地方。如果你使用observeEventType:withBlock:,你会得到同样的FDataSnapshot

如果出现问题,您将收到error

如果您的数据已提交,committed 将为 YES。如果您在事务块中返回[FTransactionResult abort] 而不是[FTransactionResult successWithValue:],则committed 将为NO。

这意味着,如果您在 4 处读取计数器并尝试更新它。您可能会尝试在其他人更新计数器的同时更新计数器。如果你先进入,snapshot.value 将是 5。如果其他人的更新在你之前进入,snapshot.value 将是 6。

无论谁先投票,您可能都想获得最多 6 个。为此,您需要添加一个观察者。其代码可能如下所示:

[upvotesRef observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) 
    NSLog(@"New Value: %@", snapshot.value);
];

有了这个,您就不需要完成块来找出最终值,因为每次事务块时,观察者块都会触发。在上面的示例场景中,无论谁先投票,它都会触发 5 次和 6 次触发。如果您想知道您的特定交易是否成功,而不仅仅是现在该位置的值是多少,您确实需要完成块。

而且,为了完整起见,还有一种称为runTransactionBlock:andCompletionBlock:withLocalEvents: 的方法。如果其他人也在写入同一位置,则事务块可能会运行多次。如果它发现它在陈旧数据上运行,就会发生这种情况。当它在新数据上成功运行时,它将调用完成块。但是,您会发现每次运行时,它都会在该位置触发任何观察者方块。如果您希望这种情况发生,您应该将 NO 传递给 withLocalEvents:。每当确认写入通过时,您的 Firebase 都会在该位置触发事件,但您本地事务的未确认临时写入不会。

回顾一下您和另一个人同时尝试投票的示例。默认情况下,一旦您尝试将计数从 4 更新到 5,观察者就会触发。实际事务可能会失败,因为其他人同时将 upvote 计数从 4 推到 5。然后,您的事务块将使用新数据 5 再次运行,并看到它应该将计数推到 6。将本地事件设置为 NO,观察者将在服务器通知您知道其他人将 upvote 计数从 4 推后触发到 5,而不是当您尝试将计数从 4 更新到 5 时。

对于像upvotes 这样简单的事情,每个人都在增加,这并不是什么大不了的事,但是如果您可能会推送来自其他用户的不同数据,那么该位置的任何观察者都可能会在最终解决之前看到数据跳跃。

【讨论】:

这个答案应该添加到 Firebase API 文档中......别开玩笑了。 老实说,它解释得很好。兄弟们干杯 @katfang 如果您可以为 Swift 编写等效的代码,那将非常有帮助。非常感谢

以上是关于Firebase如何检查交易成功或失败?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改firebase存储的位置?

如何一次执行四个查询然后检查成功或失败?

SQL Server 维护计划历史记录检查成功或失败

应用程序在调试时运行时如何禁用 Firebase 崩溃报告?

GraphQL 检查区块链上是不是存在交易

如何在使用firebase作为服务器或数据库的cordova应用程序中实现通知