公开访问Firestore收藏文档

时间:2020-06-21 21:10:58

标签: javascript firebase google-cloud-firestore firebase-security

我需要允许对集合的公共访问,但仅用于查询特定文档且前提是它与前提条件匹配。

例如,我有一个集合opam pin add --dev-repo zarith opam install zarith ,其中包含文档:

userdata

我需要创建一个规则,仅在使用5a70afcd3b26d6a5: { id: 7799389, email: me@domain.com ... } read查询集合(甚至在身份验证之前)时才允许id访问,否则不行。可能吗?

3 个答案:

答案 0 :(得分:1)

我对您的要求的理解:您希望用户仅在事先知道某些特定字段的情况下才能够从给定集合中检索文档。

以您的示例为例,使用字段email{id}_{email},一种解决方案是命名文档7799389_me@domain.com: { id: 7799389, // May be omitted as already in the doc name email: me@domain.com // May be omitted as already in the doc name ... } get: allow if... // additional conditions if needed ,仅提供获取规则。文件名称本身就是秘密。

this.message$.pipe(
  filter(m => m.channel === channel),
  map(m => m.data)
);

如果您不想或无法更改文档ID,则需要根据用户请求将文档与某些条件进行匹配,如果用户未经身份验证,这几乎是不可能的。

答案 1 :(得分:0)

使用您当前的结构是不可能的。但是,可以通过在安全规则中使用request.query来解决。

例如

service cloud.firestore {
  match /databases/{database}/documents {
    match /userdata/{userid} {
      // Deny any query not limited 1 and contains offset or orderBy.
      allow list: if request.query.limit == 1 && !request.query.offset && !request.query.orderBy;
    }
  }
}

这样做,您仅将集合中的第一个文档公开,其他的仅在特定条件下可查询。

另一种可能的解决方案是像@Oliver回答一样重新组织您的收藏集,并仅允许按ID查询。请注意,尽管在ID中使用.[之类的特殊字符。

最后但并非最不重要的一点是,编写一个接受电子邮件和id作为参数并返回doc作为结果的云函数。它可能比直接使用Firestore慢。

答案 2 :(得分:0)

如果您的实际需要是只允许用户查看自己的记录,我只是在徘徊?

如果是这样,我建议-

  1. 要求用户首先由Firebase进行身份验证才能获得Firebase身份验证令牌。

  2. 用户必须使用在上述步骤中获得的firebase令牌登录到服务器。

  3. 在您的身份验证逻辑中,将令牌中嵌入的Firebase UID映射到用户ID和电子邮件。我假设您有一个表(确切地说是集合,在firebase中)来保存这种关系。

  4. 将在上述步骤中获得的用户ID和电子邮件保存为Firebase令牌声明。这是C#代码示例,您应该可以在javascript中类似地完成操作-

    等待FirebaseAdmin.Auth.FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync( uid, 新字典 { {“ user_id”,userId}, {“ user_email”,userEmail} });

  5. 创建以下数据规则以确保用户只能读取自己的记录-

    match /userdata/{user} {
       allow read: if resource.data.userid == request.auth.token.userid &&
                      resource.data.userEmail == request.auth.token.userEmail 
     }     
    

如果userid足以唯一标识用户,则无需将userEmail保存在令牌声明中,也不需要在规则中进行检查。