用于 Firebase 规则的 JsonPath

JsonPath used for Firebase Rules

我有以下数据:

我有以下代码:

   findChats(): Observable<any[]> {
        return this.af.database.list('/chat/', {
            query: {
                orderByChild: 'negativtimestamp'
            }
        }).map(items => {
            const filtered = items.filter(
                item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
            );
            return filtered;
        });
    }

如果我使用上面的 JsonPath ('/chat/') 访问数据库,它 returns 所有匹配的行,然后代码过滤结果。

我确实定义了以下数据库规则:

{
  "rules": {
      "chat": {
        "$key": {
            ".read": true
        }
      },
                ....

我在模拟器中测试的是:

/chat/-Ko7w9XTtuRVN4p6CMp7/memberId

它找到了一个匹配项。

现在当我 运行 使用此规则的代码时,我得到:

Error: permission_denied at /chat: Client doesn't have permission to access the desired data

问题

我无法让代码 JsonPath 通过规则的原因是因为它只是 /chat/ 吗?

为了匹配规则,代码 JsonPath 是否也必须包含 $keymemberId

例如/chat/-Ko7w9XTtuRVN4p6CMp7/memberId

正如您从我的代码中看到的那样,我正在尝试获取过滤后的 chats 列表,并且代码不知道 $key 值是什么。那么是否不可能将规则应用于只允许访问匹配行的查询?

更新

我的问题类似于。我尝试了以下但没有成功:

{
  "rules": {
      ".write": "auth != null",
      "chat": {
        "$id": {
            ".read": true
        }
      },

更新

我目前有以下规则,该规则有效,但还不够。它检查用户是否已通过身份验证,但不检查他们的 auth.id 等于 memberId1memberId2.

{
  "rules": {
    "chat": {
      ".read": "auth != null",
      ".write": "auth != null"
    },
    "message": {
      ".read": "auth != null",
      ".write": "auth != null"
    }
  }
}

您收到错误的原因是 Firebase 规则级联。

请查看 this doc 的 "Read and Write Rules Cascade" 和 "Rules Are Not Filters" 部分。

级联本质上意味着以下内容:-

.read and .write rules work from top-down, with shallower rules overriding deeper rules. If a rule grants read or write permissions at a particular path, then it also grants access to all child nodes under it.

因此,如果规则限制访问(或者如果规则不存在)到更高的节点,那么您将无法访问该节点。

因此,在您的情况下,您可以通过从客户端代码访问 /chat/-Ko7w9XTtuRVN4p6CMp7/memberId 路径来测试它,您会发现它可以正常工作。

Firebase 文档中的以下示例是您情况的副本:-

Rules are applied in an atomic manner. That means that a read or write operation is failed immediately if there isn't a rule at that location or at a parent location that grants access. Even if every affected child path is accessible, reading at the parent location will fail completely. Consider this structure:

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

Without understanding that rules are evaluated atomically, it might seem like fetching the /records/ path would return rec1 but not rec2. The actual result, however, is an error: