Firestore安全规则:为什么我可以读取数据?

时间:2020-09-11 18:47:42

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

我有一个名为myusers的Firestore集合,其中有大约200个文档,其中包含有关用户的信息,例如电子邮件,姓名等。文档ID是Firebase uid。

我设置了以下安全规则

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        
        function isRestaurant() {
            return request.auth.uid == 'agivenuser' || request.auth.uid == 'anothergivenuser';
          }
    
        match /myusers/{user} {
          allow read: if resource.data.userId == request.auth.uid || isRestaurant();
          allow create: if request.auth.uid != null;
            
            match /mytok/{doc}/{document=**} {
                allow read: if request.auth.uid == user || isRestaurant();
                allow create: if request.resource.data.userId == request.auth.uid;
            }   
        }
      }

现在,我尝试使用一个没有将isRestaurant()设置为true的用户登录,并且看起来该用户可以访问整个 myusers 集合。我认为resource.data.userId == request.auth.uid基本上可以使用户看到其 uid 与给定文档的 userId 字段匹配的文档。实际上,他可以看到整个集合以及其中的所有文档。

请注意,当我尝试使用getDocuments()读取集合时,我将无法读取任何文档,但是如果创建流,则好像可以读取所有内容。

这是我的get文档代码(无法读取集合)

  void check() async {    
    final QuerySnapshot result = await Firestore.instance.collection('myusers').getDocuments();
    final List<DocumentSnapshot> documents = result.documents;
    documents.forEach((element) {
      print(element['email']);
    });

这是StreamBuilder的代码(这使我可以打印集合中每个文档的所有电子邮件)

    Stream myStream;
    @override
    void initState() {
      super.initState();
      myStream = _firestore.collection('myusers').snapshots();
    }

              SliverList(
                delegate: SliverChildListDelegate([
                  StreamBuilder<QuerySnapshot>(
                    stream: myStream,
                    builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
                      if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
                      switch (snapshot.connectionState) {
                        case ConnectionState.waiting:
                          return new Text(
                            'Loading...',
                            style: kSendButtonTextStyle.copyWith(color: kColorText),
                          );
                        default:
                          customerDB = snapshot.data.documents;
                          snapshot.data.documents.forEach((element) {
                            print(element['email']);
                          });
                          return new ListView(
                            shrinkWrap: true,
                            physics: ClampingScrollPhysics(),
                            children: customerDB.map((DocumentSnapshot document) {
                              return Padding(
                                padding: const EdgeInsets.symmetric(horizontal: 8.0),
                                child: Card(
                                  color: kColorPrimaryLight,
                                  child: ListTile(
                                    title: Text(
                                      (document['userName'] ?? 'xxx'), 
                                  ),
                                ),
                              );
                            }).toList(),
                          );
                      }
                    },
                  )
                ]),
              ),

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

使用类似这样的内容:

var newDOM = new ActiveXObject("Msxml2.DOMDocument.6.0");

这将允许任何经过身份验证的用户创建新数据,但只有拥有文档的用户才能修改该文档。

答案 1 :(得分:0)

resource.data.userId == request.auth.uid OR isRestaurant()匹配的任何用户都可以读取资源。

请确认您没有使用使isRestaurant评估为true的用户。