首页 > 解决方案 > Firestore 规则,request.auth.uid 与我从 firebase auth google signin 获得的 uid 不同

问题描述

对 Firestore 安全规则感到困惑。

我正在使用cordova插件:cordova-plugin-firebasex在firestore中进行身份验证和处理存储用户数据。

我的firestore结构如下:

firestore database > collection: [uid] > bunch of documents

我通过创建一个经过身份验证的集合来存储用户数据,User UIDAuthentication > UsersFirebase 身份验证控制台面板中所示。

但是,当我创建以下规则时。他们总是决心为假。即使我手动将 UID 字符串放入替换userId>allow read, write: if request.auth.uid == <copied User UID>;它解析为 false。

rules_version = '2';
service cloud.firestore {
  match /databases/{database} {
    match /{userId} {
      allow read, write: if request.auth.uid == userId;
    }
  
  }
}

编辑: 感谢@doug 指出文档通配符。

工作规则如下:(注意/databases/{database}/documents<- 缺少文档)并在集合中添加通配符

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{userId}/{document=**} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

标签: firebasegoogle-cloud-firestorefirebase-authenticationfirebase-security

解决方案


首先,从建模的角度来看,给每个用户自己的顶级集合并不是一个好主意。相反,您应该在单个集合(例如“用户”)中给他们每个文档,然后根据需要在该集合下给他们子集合。使用 Firestore 一段时间后,您可能会明白为什么会这样,但即使您现在不明白,我建议您将其更改为更接近您在文档中看到的内容。

您现在拥有的规则不起作用,因为它与任何文档都不匹配。您至少需要两个组件来匹配文档。如果要匹配集合中的所有文档,则需要另一个通配符:

rules_version = '2';
service cloud.firestore {
  match /databases/{database} {
    match /{userId}/{docId} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

推荐阅读