Firestore安全规则:无法检查子集合中的文档是否等于用户UID

时间:2019-04-25 01:01:12

标签: firebase validation firebase-authentication google-cloud-firestore firebase-security-rules

问题

我目前正在实施一个系统,用户可以使用它存储在根集合中,而其他用户使用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无效。

在此先感谢您的帮助

1 个答案:

答案 0 :(得分:0)

在安全规则中,您无法检查集合中是否存在具有特定值的文档,因为这意味着规则必须读取集合中的所有文档,这使它们变得缓慢,昂贵/不可扩展。

但是,您可以做的是检查是否存在具有特定ID的文档。因此,如果文档以投票的UID命名,则可以检查用户是否已经投票。

要检查文档是否已存在,请使用exists函数,如下所示:https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents