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

Ree*_*eed 5 objective-c ios firebase

我正在尝试更新事务中的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];
}];
Run Code Online (Sandbox Code Playgroud)

最大的问题是: 如何检查此交易的结果(成功/失败)?我希望做一些UI更改取决于它的结果.

SDK文档中还有另一种方法似乎有回调,但它没有解释我应该检查哪个值.它说有关该方法的一些内容可以多次运行.如何确定何时给出"最终"结果? https://www.firebase.com/docs/ios-api/Classes/Firebase.html#//api/name/runTransactionBlock:andCompletionBlock:

对不起,我是一个初学者,如果没有一些例子,苹果风格的文档真的不会聚在一起.

小智 11

如果您只想等待最终值,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);
}];
Run Code Online (Sandbox Code Playgroud)

那里的最后一个价值snapshot.value就是你可以获得最终价值的地方.它与FDataSnapshot你使用的相同observeEventType:withBlock:

如果出现问题,你会得到一个error.

如果您的数据已提交,则为committedYES.如果您[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);
}];
Run Code Online (Sandbox Code Playgroud)

这样,您不需要完成块来查找最终值,因为每次事务阻塞时,观察者块都将触发.在上面的示例场景中,无论谁首先投票,它都会为5次触发一次,为6次触发一次.如果要查明特定事务是否成功而不是现在该位置的值,您确实需要完成块.

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

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

对于像每个人只是递增的upvotes这样简单的东西来说,这并不是什么大不了的事,但如果你可能会从其他用户那里推送不同的数据,那么该位置的任何观察者都可能看到数据在最终解决之前跳了起来.

  • 这个答案应该添加到Firebase API文档中......不要开玩笑. (4认同)