Firebase 数据库规则 - `data.exists()` 似乎总是正确的,可能是错误?

Firebase database rules – `data.exists()` always seems to be true, possible bug?

我正在尝试保护我的 firebase 数据库以允许创建新记录,但不允许删除现有记录。最终,我计划在我的应用程序中也使用 Firebase 身份验证,并允许用户更新现有记录(如果他们是作者),但我试图让简单的案例首先起作用。

但是!无论我在数据库规则模拟器中尝试什么,无论文档 seems to suggest, the value of data.exists() seems to always be true. From what I what I can understand from the documentation 是什么,变量 data 都代表数据库中的一条记录,就像它在操作发生之前所做的那样。也就是说,对于creates,data不会存在,而对于updates/deletes,data会引用数据库中存在的真实记录。 这似乎不是这种情况,以至于我实际上怀疑 Firebase 中的错误,因为在我的数据库上设置以下规则时,所有写操作不允许:

{
  "rules": {
    ".read": true,
    ".write": "!data.exists()"
  }
}

无论我在模拟器中输入什么值,无论是位置还是数据。我什至编写了一个小的 EmberJS 应用程序来验证模拟器是否在说真话,并且它也被拒绝了所有写入操作的权限。

我真的不知道从这里到哪里去,因为我几乎没有什么可以尝试的。我尝试从我的数据库中删除所有记录,这让模拟器认为它可以执行写操作,但我的测试应用程序仍然得到 PERMISSION_DENIED,所以我不知道是什么导致了那里的不一致。

我对预定义 data 变量的理解是否正确?如果是这样,为什么我不能编写我想要的规则?我已经看到 snippets 字面上试图实现我的 "create only, no-delete" 规则,这似乎符合我的理解。

最后说明:我正在一个全新的 Firebase 项目中尝试使用上述规则,而且我的数据库中只有几条垃圾数据记录。

因为您将 !data.exists() 放在数据库的根位置,所以 data 指的是整个数据库。只有当数据库完全为空时,您才能写入数据库。

你表示你 运行 你的测试只用 我的数据库周围的一些垃圾数据记录 。这些记录将导致 data.exists() 为真。

您可以通过将 !data.exists() 规则放置在树中您希望不存在任何数据的特定位置来实现您的目标。这通常在具有通配符键的位置完成,如您链接的示例所示:

{
  "rules": {
    // default rules are false if not specified

    "posts": {
      ".read": true, // everyone can read all posts

      "$postId": {
        // a new post can be created if it does not exist
        // existing posts can only be edited by their original "author"
        ".write": "!data.exists() && newData.exists() || data.child('author').val() == auth.uid",
        ".validate": "newData.hasChildren(['title', 'author', 'timestamp'])",
      }
    }
  }
}