Firebase:有没有办法看到从SDK发送的JSON有效负载?

时间:2016-10-31 21:41:07

标签: ios objective-c firebase firebase-realtime-database firebase-security

我使用Firebase开发了一个iOS应用程序已有几个月了,而且我遇到了一个问题,即对我的后端的调用失败了。为了测试这个问题,我在Firebase上打开了模拟器并模拟了调用,并且没有任何问题。所有其他呼叫都按预期工作。

我能得出的唯一结论是,JSON有效负载在某种程度上与我预期的有所不同。

一些细节: 我所在的视图控制器正在连续观察后端的数据结构(使用 observeEventOfType:withBlock:withCancelBlock:),并且该屏幕上的复选框操纵相同数据结构的子值。因此,每次选中或取消选中某个框时,它都会使用新值执行 setValue:调用。然后,由于正在观察父数据结构,它将被更新,并刷新屏幕。

我遇到的问题是 setValue:调用被拒绝,而这反过来又击中了另一个方法的cancelBlock。当我尝试在Firebase信息中心上模拟 setValue:时,它会成功。

我在github gist中添加了相关的后端规则和有问题的失败方法: 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()"
        }
    }
}

方法失败(目标-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"
}

模拟器的明显成功: sensitive information redacted

2 个答案:

答案 0 :(得分:0)

最近,你可以enabling debug logging

FIRDatabase.setLoggingEnabled(true)

答案 1 :(得分:0)

我终于弄明白了。

我评论了所有验证规则,以便我可以将任何我想要的内容发布到后端。到目前为止,我已经想到,因为我将我的布尔值包装在NSNumber中,所以我认为后端会将该值存储为数字。因此,我对该路径的规则是newValue.isNumber()。然而,事实证明,Firebase自动知道它是一个布尔值,所以当我删除所有规则时,发布到后端的值是“真的”。所以,我把规则改写为newValue.isBoolean()现在它运作得很好。

故事的道德:如果使用布尔值初始化NSNumber,那么当您将其移交给Firebase时,创建的JSON有效负载将在意识到NSNumber是布尔值开头。