我目前正在实施一个系统,用户可以使用它存储在根集合中,而其他用户使用Firestore创建的想法可以投票,该投票存储在该想法的子集合中。
每个用户只能对每个想法投票一次,而且系统必须安全(您不能删除其他人的投票或像其他人一样创建投票)
如何检查用户是否已经通过安全规则投票?它不是必需的,但是我宁愿不使用get(),而是使用文档ID作为标识符。
在Firestore安全规则中,我对用户进行了简单的验证,以创建有效的想法。
然后,我允许他们在(idea_likes)子集合内创建投票文档,我尝试检查投票文档通配符是否与用户ID匹配没有成功,但是设法检查了字段userid是否与auth.userid匹配。使得对客户端进行编码以显示用户是否已投票的一点点困难。
这是我允许某人创建想法的方式:
match /ideas/{document} {
// Anyone signed in can create ideas
allow create: if isSignedIn()
// Idea creation data validation
&& documentRequestNewData().idea is string
&& documentRequestNewData().title is string
&& documentRequestNewData().owner is string
&& documentRequestNewData().votes is number
&& documentRequestNewData().date is timestamp;
}
下面是我试图允许某人创建投票的方式:
match /ideas/{document}/idea_likes/{likeId} {
allow create, delete: if isSignedIn()
&& request.resource.data.owner == request.auth.uid
&& request.auth.uid == likeId;
}
我也尝试过拆分{likeId}通配符:
match /ideas/{document}/idea_likes/{likeId} {
allow create, delete: if isSignedIn()
&& request.resource.data.owner == request.auth.uid
&& likeId.split('/')[2] == request.auth.uid;;
}
仅检查文档字段有效,但无助于避免重复投票:
match /ideas/{document}/idea_likes/{likeId} {
allow create: if isSignedIn()
&& request.resource.data.owner == request.auth.uid;
}
我希望,如果用户创建一个ID等于其用户ID的投票文档,则可以避免重复投票,并使在前端查询此数据变得容易。
但是,如所示使用通配符并检查它是否等于request.auth.uid无效。
在此先感谢您的帮助
答案 0 :(得分:0)
在安全规则中,您无法检查集合中是否存在具有特定值的文档,因为这意味着规则必须读取集合中的所有文档,这使它们变得缓慢,昂贵/不可扩展。
但是,您可以做的是检查是否存在具有特定ID的文档。因此,如果文档以投票的UID命名,则可以检查用户是否已经投票。
要检查文档是否已存在,请使用exists
函数,如下所示:https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents。