Cloud Firestore 安全规则在生产代码中为 resource.data 提供空值

Cloud Firestore Security Rules give null for resource.data in production code

我正在开发一款教育应用程序,让教师可以访问基于共同主题的学生作业文件。我为老师设置了一个自定义声明客户端,并设置了具有公共字段“主题”的文档。我的规则如下所示:

    match /assignments/{entry} {

        allow read: if isSignedIn() && resource.data.subject == request.auth.token.subject;
        allow write: if request.auth.token.moderator == true;


    //TODO: assignment rules go here
    function isSignedIn() {
    return request.auth.uid != null;
    }
        
    }
  }

尽管如此,我还是无法获得提取任何数据的资源。甚至 resource.data != null 显示错误。

我的自定义声明顺利通过,request.auth.token.subject == "Biology" 显示我的示例帐户为真。

这里是查询:

_guestBookSubscription = FirebaseFirestore.instance
            .collection('assignments')
            .orderBy('start_date', descending: true)
            .limit(30)
            .snapshots()
            .listen((snapshot) {
          _guestBookMessages = [];
          for (final document in snapshot.docs) {
            _guestBookMessages.add(RTIAssignment(
              // endDate: (document.data()['end_date'] as DateTime),
              standard: document.data()['standard'] as String,
              startDate: DateTime.now(), // (document.data()['start_date']),
              student: Student(name: document.data()['student_name']),
              subject: document.data()['subject'] as String,
              teacher: document.data()['name'] as String,
            ));
          }
          notifyListeners();
        });

来自the nifty codelabs on writing queries that Google puts out.

我不确定如何复制查询的目标文档。它在 Firebase 中,其中一个字段是“主题”。

Firestore 规则不适用于对可以下载和不能下载的数据进行排序。您可能查询不包含 where() method/function 的数据。 Firestore 认为您要查询所有文档,因此他拒绝整个查询。

在您的查询中包括:

JavaScript

const q = query(citiesRef, where("subject", "==", "Biology"));
...

db.collection("cities").whereField("subject", isEqualTo: "Biology")

可能第二种 .whereField() 方法适用于 flutter,但我不知道。

规则应该是这样的:

match /databases/{database}/documents {
    match /{document=**} { // here you restrict access to whole database
      allow read, write: if false;
    }
    match /assignments/{docID} { // here except data to whole database was restricted you allow to read write documents in this collection path.
        allow read: if isTeacher() || isModerator()
        allow write: if isModerator()
    }
    function isTeacher() {
        return request.auth.token.subject == resource.data.subject
    }
    function isModerator() {
        return request.auth.token.moderator == true;
    }
  }

教师 token.subject == "Biology" 只能请求字段 subject == "Biology" 的文档,因此他们需要在查询中使用 whereField()。如果教师主题是“数学”,他只需要请求文件 whereField("subject", isEqualTo: "Math") 主持人无需使用“whereField()”,他们可以阅读整个数据。