我想只对Firestore数据库集合中的一个字段提供写/更新访问权限,而无需请求auth服务。我对Firestore的规则是:
service cloud.firestore {
match /databases/{database}/documents {
match /businesses/{businessId} {
allow read;
allow write: if request.auth.uid != null;
}
}
}
我的businesses
的数据库结构是:
addedBy: string;
address: string;
category: string;
claim: boolean;
city: string;
email: string;
id: string;
likes: number;
location: {
_lat: number,
_long: number
};
name: string;
ocHours: [{
day: string,
from: string,
status: string,
to: string
}];
phone: number;
sponsored: boolean;
state: string;
status: string;
verificationCode: string;
我只想更新claim
字段,而不更新request.auth.uid != null
。
有什么建议吗?
答案 0 :(得分:4)
我不知道该线程是否仍然有效,但是在寻找一个偶然发现的解决方案时,我偶然发现了rules.MapDiff
规范,它完全符合您的期望:
// Compare two Map objects and return whether the key "a" has been
// affected; that is, key "a" was added or removed, or its value was updated.
request.resource.data.diff(resource.data).affectedKeys().hasOnly(["a"]);
有关详细信息,请参见此处https://firebase.google.com/docs/reference/rules/rules.MapDiff
答案 1 :(得分:1)
如this blog post中所述,request.resource.data
不仅包含更新的字段,而且还包含整个将来状态(如果写入成功)。
因此,您可以简单地检查资源中的字段是否与请求中的字段不同,并按照作者的巧妙建议,创建如下函数:
function notUpdating(field) {
return !(field in request.resource.data) || resource.data[field] == request.resource.data[field]
}
在您的情况下,您可能希望将write
分解为create
,update
,delete
,而update
可能看起来像这样:
allow update: if
notUpdating(addedBy)
&& notUpdating(address)
&& notUpdating(category)
// ... put all fields here except 'claim'
&& notUpdating(status)
&& notUpdating(verificationCode) ;
答案 2 :(得分:0)
授权应用于整个文档。您可以创建由business-uid标识的文档的“声明”集合,并将其设置为write
,这样公众无法读取列表,但是他们可以更新claim
属性。这些文档可能是布尔值,例如
home/claimsCollection
bizABC123
claim:true
bizXYZ123
claim:false
答案 3 :(得分:0)
权限分配只能应用于整个文档。 尽管如此,仍然存在一种允许写入/更新/删除/创建特定文件的方法,即通过确保传入的更改对象仅具有您要授予权限的字段。 您可以通过以下方式做到这一点:
request.resource.data.keys()
hasOnly["claim"]
service cloud.firestore {
match /databases/{database}/documents {
match /businesses/{businessId} {
allow read;
allow write: if request.resource.data.keys().hasOnly["claim"];
}
}
}
希望它会有所帮助,尽管问题已经发布了一阵子了!
答案 4 :(得分:0)
我编写了以下函数,用于仅允许一个字段可编辑:
function onlyField(field) {
return request.resource.data.keys().hasOnly([field]);
}
此功能可以如下使用:
match /someObject/{document=**} {
allow update: if onlyField('someFieldOfYOurObject');
}