在实时数据库(在 Firebase 上)中,我对名为 Resource 的集合有以下规则:
{
"rules": {
....
"Resource": {
".read": true,
".indexOn": ["FieldOne","FieldTwo"]
},
....
}
}
事情如我所愿。不过我还是想做出一些改进。
这是我的问题。此时,我可以使用如下命令从 CLI 将文档添加到集合中:
firebase database:push /..path../Resource --data '{"FieldOne":"field-1-value","FieldTwo":"field-2-value"}'
当然,我也可以用不同的方式添加文档。但我的问题是,我可以重复上述相同的命令,并在资源集合中再次添加相同的文档。
我想知道如何改变我的规则以避免添加重复数据的可能性。
正是我想要的,执行上述命令后,我仍然能够将这些文档插入到集合中:
{"FieldOne":"field-3-value","FieldTwo":"field-4-value"}
{"FieldOne":"field-1-value","FieldTwo":"field-5-value"}
{"FieldOne":"field-7-value","FieldTwo":"field-2-value"}
但是,我不能插入这个:
{"FieldOne":"field-1-value","FieldTwo":"field-2-value"}
当然,我可以编写代码来控制传入的内容,无论是使用云函数还是通过 Web 界面输入数据。但这不是本问题的重点。我只是想知道是否有一种巧妙的方法来设置规则,从一开始就防止出现不需要的数据。
Firebase 实时数据库没有内置支持来防止重复值。
另一方面,节点中的键必须保证始终是唯一的。这意味着您通常希望将希望唯一的值存储在数据库/JSON 中的键中,而不是值中。
我们先来看看目前的情况
当您调用 push/POST 时,Firebase 会生成唯一键
当您调用
push
Firebase(或其POST
REST API)时,数据库或 SDK 会为您生成一个唯一密钥。因此,在您的包含三个子节点的示例中(正如 Doug 所评论的那样,Firebase 实时数据库没有文档或集合的概念,我将在这里使用正确的术语以避免混淆),JSON 实际上将是这样的:这些以 开头的键
-
是 Firebase 生成的推送键。因此,如果您push
再次调用 /POST(使用不同或相同的值),它会生成另一个唯一键。根据必须唯一的值生成密钥
为了防止重复,您必须确保键是值的表示 - 这样,如果您第二次传递相同的值,您将获得相同的键。
一种方法是简单地连接值并将其用作键。这样上面的 JSON 就会变成:
在此结构中,如果您将相同的值传递到数据库中,它将具有相同的键。正如开头所述:节点中的键保证始终是唯一的。因此,根据您使用的操作,第二次写入相同的值/键将被拒绝,或者它将覆盖现有值(具有相同的值,因此这是无操作)。
使用
set
/PUT 而不是push
/POST要编写上述指定您自己的密钥的结构,您需要使用
set
/PUT 操作,而不是使用push
/POST。因此,使用 Firebase CLI 的示例将变为:在这里你可以看到我们现在:
database:set
而不是database:push
field-1-value_field-2-value
键),而不是仅告诉它我们想要在其下添加新内容的父节点。这个主题之前已经讨论过了,所以我建议你看一下: