2017-07-06 13 views
0

我想确保我的firebase数据库允许创建新记录,但不允许删除现有记录。最终,我计划在我的应用中使用Firebase身份验证,并允许用户更新现有记录(如果他们是作者),但我试图首先让这个简单案例工作。Firebase数据库规则 - `data.exists()`似乎总是如此,可能的错误?

但是!不管我在数据库规则模拟器中尝试什么,尽管文档seems to suggestdata.exists()的值似乎总是如此。从我从the documentation中可以理解的内容可知,变量data代表数据库中的记录,与操作发生之前一样。也就是说,对于创建,data不存在,并且对于更新/删除,data将引用存在于数据库中的真实记录。 这似乎并没有这样的情况,到了那里我居然怀疑一个bug在火力地堡,因为在我的数据库中设置以下规则当点,所有的写操作是不允许的

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

无无论我将什么值放入模拟器,无论是位置还是数据。我甚至写了一个小的EmberJS应用程序来验证模拟器是否说出了真相,并且它也被拒绝了所有写入操作的许可。

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

是我对预定义的data变量的理解是否正确?如果是这样,为什么我不能写出我想要的规则?我看到snippets字面上试图达到我的“创造唯一,不删除”规则,似乎与我的理解相符。

最后说明:我正在尝试在一个全新的Firebase项目中使用上面的规则,并且只有〜少数记录我的数据库周围的垃圾数据。

回答

2

由于您已将!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'])", 
     } 
    } 
    } 
} 
+0

嗨,感谢您的回复。这是我理解中的缺失部分,我显然没有正确解析文档。我实现了像这样的变化,现在一切都按预期工作100%。我假定“数据”是一种神奇解决的变量,它是根据您的要求推断的,而不是基于规则本身。谢谢! – Peabnuts123