您如何调试Firestore安全规则?

时间:2018-10-17 08:56:17

标签: firebase google-cloud-firestore firebase-security-rules

我在哭自己要睡这个。

我的getAfter返回的对象只有一个字段,因为其他所有字段类型都不正确。我不知道如何在没有任何调试工具的情况下进行检查(我看不到数据,因此只能进行猜测和检查)。

这是我对users的规则的简化版本。

match /users/{userId} {
  function isValidUser(user) {
    return user.id is string &&
       (user.address is string || user.address == null) &&
       (user.dateOfBirth is number || user.dateOfBirth == null) &&
       user.email is string &&
       user.name is string &&
       (user.phoneNumber is string || user.phoneNumber == null);
  }

  function isValidWrite(userId, user) {
    return signedIn() && 
        writeHasMatchingId(userId, user) &&
        isValidUser(user);
  }

  allow read: if signedIn();
  allow create: if signedInAndWriteHasMatchingId(userId) &&
    userHasId(userId) &&
    isValidUser(request.resource.data); // Tested
  allow update: if isValidWrite(
    userId,
    getAfter(/databases/$(database)/documents/users/$(userId))
  );
}

这是我要运行的事务。

const user1Ref = this.userCollection.doc(user1Id);
const user2Ref = this.userCollection.doc(user2Id);
const batchWrite = this.store.batch();

batchWrite.update(user1Ref, {
     "details.friend": user2Id,
});
batchWrite.update(user2Ref, {
     "details.wishlist": true,
});

batchWrite.commit();

如果我注释掉isValidUser(user)行,则操作成功。如果我在function isValidUser(user)内除user.id is string以外的任何地方都未加注释,它将失败。

getAfter文档在Firebase控制台中列出时,为什么id文档仅包含getAfter字段?有没有一种方法可以输出或调试AND (v_start_date IS NULL AND v_end_date IS NULL) OR audit_start_time BETWEEN v_start_date AND v_end_date 的值,这样我什至可以看到它是什么?

2 个答案:

答案 0 :(得分:5)

我要回答的只是您的一句话:

有没有一种方法可以输出或调试getAfter的值,这样我什至可以看到它是什么?

至少在2020年是这样。

在“规则游乐场”中运行某项内容时(“规则模拟器”,见左下图),规则评估中采取的步骤如下所示:

enter image description here

此列表有时会提供一些指示,以帮助弄清规则评估者的工作。需要单独单击“打开”的步骤有点麻烦,而不是仅仅看一眼就可以看到是非。但这总比没有好。

注意:我认为Firebase正在开发此功能。有时似乎提供了错误的信息-或我未能正确阅读它。但这可能会有所帮助,并且看起来是向开发人员提供此类信息的好地方。我们真的很想看到:使用当前数据,构建的查询文档和规则,Firebase如何看待它,以及为什么规则的评估结果为true或false?

答案 1 :(得分:0)

另一种方法(此处尚未提及且在提出问题时可能不可用)是用 debug() 包装您的规则。

为什么这很酷?

  • 允许查看怀疑不正确的值;我仍然使用@ColdLogic 在他们的评论中很好地描述的相同的注释缩小方法

为什么这还不够?

  • 没有关于输出哪个值的标记;只是例如。 int_value: 0。调试将受益于例如。在输出中打印它正在评估的方程的前 10 个字母。

  • 拒绝安全规则的原因仍然非常短,如 false for 'update' @ L44

    • 行号始终指向正在计算的主表达式。永远不要调用真正导致失败的函数或带有 && 的子表达式。

    Firebase 可以解决这个问题(不改变输出语法;只提供更详细的行号)。这将消除注释和缩小范围的需要。

  • 输出到 firestore-debug.log(相当隐藏),因此需要打开另一个终端并密切关注它。

调试安全规则是不必要的困难 - 恐怕这意味着人们没有充分利用他们的潜力。我们应该改变这一点。