Firebase:有没有办法查看从 SDK 发送的 JSON 负载?
Firebase: Is there a way to see the JSON payload being sent from the SDK?
几个月来我一直在使用 Firebase 开发 iOS 应用程序,但我 运行 遇到了调用我的后端失败的问题。为了测试这个问题,我在 Firebase 上打开模拟器并模拟调用,它成功了,没有任何问题。所有其他调用都按预期工作。
我能得出的唯一结论是 JSON 有效载荷在某种程度上与我预期的有所不同。
一些细节:
我所在的视图控制器正在持续观察后端的数据结构(使用 observeEventOfType:withBlock:withCancelBlock:),并且该屏幕上的复选框操作相同的子值数据结构。因此,每次选中或取消选中一个框时,它都会使用新值调用 setValue:。然后,由于正在观察父数据结构,它得到更新,屏幕被刷新。
我遇到的问题是 setValue: 调用被拒绝,这又会触发另一个方法的 cancelBlock。当我尝试在我的 Firebase 仪表板上模拟 setValue: 时,它成功了。
我在此处的 github 要点中添加了相关的后端规则和有问题的失败方法:
https://gist.github.com/jakehawken/4a4bb8d2f58c651d7310b3a1737bf11e
//RELEVANT BACKEND RULES FOR THE FAILING CALL (I'm writing to the "completed" path):
"subtasks": {
"$list_item": {
".validate": "newData.hasChildren(['subtaskDescription', 'completed'])",
"subtaskDescription" : {
".validate" : "newData.isString()"
},
"completed" : {
".validate" : "newData.isNumber() && !newData.hasChildren()"
}
}
}
失败的方法调用(Objective-C):
- (KSPromise *)markSubtask:(HDInProgressSubtask *)subtask completed:(BOOL)completed forListID:(NSString *)listID inProgressItemKey:(NSString *)inProgressKey subtaskKey:(NSString *)subtaskKey
{
KSDeferred *deferred = [KSDeferred defer];
FIRDatabaseReference *specificSubtaskReference = [self specificSubtaskCompletionReferenceForListID:listID inProgressItemKey:inProgressKey subtaskKey:subtaskKey];
FIRDatabaseReference *subtaskCompletionReference = [specificSubtaskReference child:kCompleted];
NSNumber *value = [NSNumber numberWithBool:completed];
[subtaskCompletionReference setValue:value withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
if (error)
{
[deferred rejectWithError:error]; //Failing case
}
else
{
[deferred resolveWithValue:@(completed)]; //Success case
}
}];
return deferred.promise;
}
调用应该只是发送数字 1 或 0(包含在 NSNumber 中的 BOOL),但是当我打开详细日志记录时,它说它正在发送这个庞然大物:
{
"d" : {
"a" : "p",
"b" : {
"d" : 1,
"p" : "<the url path for this upload>"
},
"r" : 11
},
"t" : "d"
}
模拟器的明显成功:
最接近的是 enabling debug logging:
FIRDatabase.setLoggingEnabled(true)
我终于自己弄明白了。
我注释掉了我所有的验证规则,这样我就可以 post 任何我想要的后端。到目前为止,我认为由于我将布尔值包装在 NSNumber 中,所以我认为后端会将该值存储为数字。因此,我对该路径的规则是 newValue.isNumber()。然而,事实证明,Firebase 自动知道它是一个布尔值,所以当我删除所有规则时,posted 到后端的值是“true”。所以,我将规则重写为 newValue.isBoolean() 现在它工作得很好。
故事的寓意: 如果您使用布尔值初始化 NSNumber,那么当您将其交给 Firebase 时,创建的 JSON 负载将是意识到 NSNumber 是一个布尔值开始。
几个月来我一直在使用 Firebase 开发 iOS 应用程序,但我 运行 遇到了调用我的后端失败的问题。为了测试这个问题,我在 Firebase 上打开模拟器并模拟调用,它成功了,没有任何问题。所有其他调用都按预期工作。
我能得出的唯一结论是 JSON 有效载荷在某种程度上与我预期的有所不同。
一些细节: 我所在的视图控制器正在持续观察后端的数据结构(使用 observeEventOfType:withBlock:withCancelBlock:),并且该屏幕上的复选框操作相同的子值数据结构。因此,每次选中或取消选中一个框时,它都会使用新值调用 setValue:。然后,由于正在观察父数据结构,它得到更新,屏幕被刷新。
我遇到的问题是 setValue: 调用被拒绝,这又会触发另一个方法的 cancelBlock。当我尝试在我的 Firebase 仪表板上模拟 setValue: 时,它成功了。
我在此处的 github 要点中添加了相关的后端规则和有问题的失败方法: https://gist.github.com/jakehawken/4a4bb8d2f58c651d7310b3a1737bf11e
//RELEVANT BACKEND RULES FOR THE FAILING CALL (I'm writing to the "completed" path):
"subtasks": {
"$list_item": {
".validate": "newData.hasChildren(['subtaskDescription', 'completed'])",
"subtaskDescription" : {
".validate" : "newData.isString()"
},
"completed" : {
".validate" : "newData.isNumber() && !newData.hasChildren()"
}
}
}
失败的方法调用(Objective-C):
- (KSPromise *)markSubtask:(HDInProgressSubtask *)subtask completed:(BOOL)completed forListID:(NSString *)listID inProgressItemKey:(NSString *)inProgressKey subtaskKey:(NSString *)subtaskKey
{
KSDeferred *deferred = [KSDeferred defer];
FIRDatabaseReference *specificSubtaskReference = [self specificSubtaskCompletionReferenceForListID:listID inProgressItemKey:inProgressKey subtaskKey:subtaskKey];
FIRDatabaseReference *subtaskCompletionReference = [specificSubtaskReference child:kCompleted];
NSNumber *value = [NSNumber numberWithBool:completed];
[subtaskCompletionReference setValue:value withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
if (error)
{
[deferred rejectWithError:error]; //Failing case
}
else
{
[deferred resolveWithValue:@(completed)]; //Success case
}
}];
return deferred.promise;
}
调用应该只是发送数字 1 或 0(包含在 NSNumber 中的 BOOL),但是当我打开详细日志记录时,它说它正在发送这个庞然大物:
{
"d" : {
"a" : "p",
"b" : {
"d" : 1,
"p" : "<the url path for this upload>"
},
"r" : 11
},
"t" : "d"
}
模拟器的明显成功:
最接近的是 enabling debug logging:
FIRDatabase.setLoggingEnabled(true)
我终于自己弄明白了。
我注释掉了我所有的验证规则,这样我就可以 post 任何我想要的后端。到目前为止,我认为由于我将布尔值包装在 NSNumber 中,所以我认为后端会将该值存储为数字。因此,我对该路径的规则是 newValue.isNumber()。然而,事实证明,Firebase 自动知道它是一个布尔值,所以当我删除所有规则时,posted 到后端的值是“true”。所以,我将规则重写为 newValue.isBoolean() 现在它工作得很好。
故事的寓意: 如果您使用布尔值初始化 NSNumber,那么当您将其交给 Firebase 时,创建的 JSON 负载将是意识到 NSNumber 是一个布尔值开始。