假设我们有一个名为todos
的Firestore集合,其中每个待办事项都将如下所示:
{
name: "Buy milk",
completed: false,
user: "eYtGDHdfgSERewfqwEFfweE" // some user's uid
}
现在,我想在更新过程中防止对user
字段进行修改(换句话说,将该字段设置为只读)。
相信我,我已经完成了研究。我的update
规则如下:
allow update: if request.auth.uid == resource.data.user
//&& !request.writeFields.hasAny(["user"]);
//&& !(request.writeFields.hasAny(["user"]));
//&& !request.resource.data.keys().hasAny(["user"]);
//&& !('user' in request.resource.data);
//&& ('user' in request.resource.data) == false;
//&& !('user' in request.writeFields);
没有(上述注释)。它们都会导致错误:Error: Missing or insufficient permissions.
。
但是...
它变得更加有趣!因为如果我们将上述某些规则用于阳性结果(又称true
),它们将起作用!
例如,这个完美(假设我们在请求中包含user
字段)
allow update: if request.resource.data.keys().hasAny(["user"]) == true;
但此操作无效(假设我们在请求中不包含user
字段):
allow update: if request.resource.data.keys().hasAny(["user"]) == false;
有人可以解释一下这是怎么回事吗?难道这实际上是Firestore中的错误?
答案 0 :(得分:0)
在“ Cloud Firestore安全规则的编写条件”部分的“数据验证”示例#2
{id: "0", regno: "01107402042", appno: "10001", certid: "1", file_name: "9bfe44de3ddb583778d2b641bdb6b79f.pdf", …}
那么service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
应该为您工作吗? CMIIW
参考:https://firebase.google.com/docs/firestore/security/rules-conditions#data_validation
答案 1 :(得分:0)
当您更新文档时,安全规则会将更新产生的文档与安全规则的条件进行比较。这意味着如果某个字段存在于服务器上的文档中,但不存在于您在更新中推送的数据中,则安全规则将从更新中的旧数据中看到该字段。例如:
在服务器上的文档存储中:
{
reviewerID: sam123,
title: "It sucks",
description: "Because it does",
rating: 1
}
然后你的更新是:
{
description: "but actually it's not so bad",
rating: 3
}
那么安全规则在request.resource.data
中看到的是:
{
reviewerID: sam123,
title: "It sucks",
description: "but actually it's not so bad",
rating: 3
}
这意味着即使更新没有将更改推送到 reviewerID
或 title
,这些字段确实存在于您正在评估的数据中。
为了确保数据不变,您需要将新数据与旧数据进行比较:
request.resource.data.reviewerID == resource.data.reviewerID
行:
!request.resource.data.keys().hasAny(["user"]);
防止数据存在于文档中是正确的。它不是允许它存在但使其不可变的东西。
见:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
来自:
https://firebase.google.com/docs/firestore/security/rules-conditions#data_validation
和:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to create a document only if that document does *not*
// contain an average_score or rating_count field.
match /restaurant/{restId} {
allow create: if (!request.resource.data.keys().hasAny(
['average_score', 'rating_count']));
}
}
}
来自: