我有以下数据库集合'/player_profiles/{userId}'
。我要使用仅request.auth.uid == userId
的规则,除非它们仅更新匹配数组的字段。我试过了,但是它拒绝了权限
match /player_profiles/{userId}{
allow write: if userId == request.auth.uid;
allow update: if (request.resource.data.keys().hasOnly(["matches"]) && request.auth != null);
}
这是Flutter代码,用于运行更新以将项目添加到matchs数组:
await DatabaseProvider()
.db
.collection(PLAYER_COLLECTION)
.document(widget.userProfile.userId)
.updateData({
'matches': FieldValue.arrayUnion([profile.userId])
});
我是Firestore规则的新手,但我认为这会起作用
能够获得我想要的以下行为:
match /player_profiles/{userId}{
allow write: if request.auth.uid == userId || (request.auth != null && request.resource.data.diff(resource.data).affectedKeys().hasOnly(["matches"]));
}
看看@Doug Stevenson的答案,尽管我可以确保他们只被允许将自己的userId放入其他人的个人资料中。
答案 0 :(得分:2)
request.resource.data.keys()
始终包含正在编写的文档中的每个字段,无论它是否正在更新。您应该使用新的MapDiff API来比较正在编写的内容和当前存在的内容。
我想你会想做这样的事情:
if
(request.resource.data.diff(request.resource.data).affectedKeys().hasOnly(["matches"]) &&
(request.resource.data.matches.toSet().difference(resource.data.matches) == [userId].toSet()) ||
request.auth == null;
我还没有测试过,但是我想你明白了。您将需要放宽使用链接的API文档来获得安全规则,以有效地使用地图,集合和列表。