Firebase 根据数据键读取规则

Firebase read rules based on data key

我的数据结构如下:

writings: {
    'xxx-key-xxx': {
        'user-id': 'xxxxx',
        'title': 'title',
        'content': 'content'
    }
}

我正在尝试只允许用户读取他的文档:

{
  "rules": {
    "writings": {
        ".read": "auth !== null && (root.child('writings').child('user-id').val() === auth.uid)",
        }
    }
}

但这不起作用。我怀疑我没有正确过滤子 user-id 键。有什么想法吗?

您正在将 auth.uid 与路径 /writings/user-id 的值进行比较,后者缺少键 xxx-key-xxx,因此这将始终为假,因为此路径中的数据不存在.您可以更改规则以获取 child 的密钥,但是,这会限制您的 .read 阅读个人 writings children 的权限,例如

{
  "writings": {
    "$wid": {
      ".read": "auth !== null && root.child('writings/$wid/user-id').val() === auth.uid"

或等效的

      ".read": "auth !== null && data.child('user-id').val() === auth.uid"
    }
  }
}

使用这些规则,您将在尝试阅读 /writings 时看到 Permission Denied - 您必须单独阅读文档,因此您必须知道每个文档的密钥。现在我们知道我们所需要的只是每个文档的键,我们需要找到一种检索它们的方法。

表示这种关系的一种常见方法是散开数据。我们有用户的 uid,我们想要他们拥有的文档的密钥。如果您要维护另一个根节点来存储每个用户的文档的密钥,并且只能由他们访问,那么您可以参考该位置来检索用户的文档。

{
  "user-writings": {
    "$uid": {
      ".read": "auth.uid === $uid",
      "$wid": {
        ".write": "auth.uid === $uid"
      }
    }
  },
  "users": {
    ...
  },
  "writings": {
    "$wid": {
      ".read": "auth.uid === data.child('user-id').val()",
      ".write": "auth.uid === newData.child('user-id').val()"
    }
  }
}

这些规则确保用户只能查看他们自己的文档,因为只能访问他们在 user-writings/$uid 中的文档密钥。当用户创建文字时,他们还需要写入 user-writings/$uid/$wid 并将值设置为 true.

现在要检索属于用户的文档,您可以使用用户的 uid 查询位置 user-writings/$uid 以检索密钥,然后必须获取每个 writings/$wid 用户的数据拥有。完全放弃 writings 并将每个用户的文档存储在数据库中相应的位置 (user-writings/$uid) 可能适合您。