Firestore:userId规则

时间:2019-04-09 07:35:10

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

我无法使用此Firestore规则。

我想写/读到user-read-only/USER-ID-HERE/business/settings

service cloud.firestore {
  match /databases/{database}/documents {

    match /user-read-only/{userId} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;

      match /{document=**} {
        allow read, update, delete: if request.auth.uid == userId;
        allow create: if request.auth.uid != null;
      }
    }
  }
}

我继续收到消息

  

FirebaseError:缺少权限或权限不足。

我已经使用模拟器尝试了许多不同的方法,并且都成功了,但是我无法从我的应用中复制。


  • 上面看起来有什么不对吗?
  • 可以简化以上内容吗?我希望用户能够控制{userId}
  • 以外的所有内容
  • 我如何知道request.auth.uiduserId是否正确填充?

这有效

service cloud.firestore {
  match /databases/{database}/documents {

    match /{userId}/{document=**} {
      allow read, write;
    }
  }
}

这不起作用

service cloud.firestore {
  match /databases/{database}/documents {

    match /{userId}/{document=**} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

2 个答案:

答案 0 :(得分:1)

根据您的评论进行更新:“目的是扩展规则,以便用户可以管理{userId}以外的任何内容”

service cloud.firestore {
  match /databases/{database}/documents {

    match /user-read-only/{userId}/{document=**} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;

    }
  }
}

请注意,create规则(从您的问题中复制)允许任何经过身份验证的用户在任何{userId}文件夹下书写。


(相反,如果您只想为business/settings子集合和文档声明一条规则,则应使用以下方法:

service cloud.firestore {
  match /databases/{database}/documents {

    match /user-read-only/{userId}/business/settings {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;

    }
  }
}

为了确保正确填充userId,您可以在创建时将其作为字段添加到文档中,并检查create的规则是否正确,如下所示:< / p>

allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.userId;

另一方面,Firebase Auth将自动确保正确填充request.auth.uid

最后,您可能会从Firebase团队观看有关安全规则的这段非常好的视频:https://www.youtube.com/watch?v=eW5MdE3ZcAw


这是用于测试的HTML页面。只需使用其他用户的ID更改userId的值即可。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script src="https://www.gstatic.com/firebasejs/5.9.3/firebase.js"></script>

    <script>
      // Initialize Firebase
      var config = {
        apiKey: 'xxxxx',
        authDomain: 'xxxxx',
        databaseURL: 'xxxxx',
        projectId: 'xxxxx'
      };
      firebase.initializeApp(config);

      firebase
        .auth()
        .signInWithEmailAndPassword('xxxxxx@gmail.com', 'yyyyyyy')
        .then(userCredential => {

          const userId = userCredential.user.uid;
          // Replace with another userId to test
          //e.g. const userId = 'l5Wk7UQGRCkdu1OILxHG6MksUUn2';

          firebase
            .firestore()
            .doc('user-read-only/' + userId + '/business/settings4')
            .set({ tempo: 'aaaaaaa' })
            .then(() => {
              return firebase
                .firestore()
                .doc(
                  'user-read-only/' + userId + '/testC/1/collec/2'
                )
                .get();
            })
            .then(function(doc) {
              if (doc.exists) {
                console.log('Document data:', doc.data());
              } else {
                // doc.data() will be undefined in this case
                console.log('No such document!');
              }
            })
            .catch(function(error) {
              console.log('Error getting document:', error);
            });
        });
    </script>
  </head>

  <body>
  </body>
</html>

答案 1 :(得分:1)

您是否部署了安全规则?

请参阅:https://firebase.google.com/docs/firestore/security/get-started#deploying_rules

  

在您可以从移动应用开始使用Cloud Firestore之前,您需要部署安全规则。您可以在Firebase控制台中或使用Firebase CLI部署规则。

您是否已使用Firebase身份验证登录?

请参阅:https://firebase.google.com/docs/firestore/security/rules-conditions

  

如果您的应用程序使用Firebase身份验证,则request.auth变量将包含客户端请求数据的身份验证信息。有关request.auth的更多信息,请参见参考文档。

您如何调用Firestore方法?

请参阅:

喜欢吗?

var userId = firebase.auth().currentUser.uid
var docRef = db.doc(`user-read-only/${userId}/business/settings`);

docRef.get().then(function(doc) {
    if (doc.exists) {
        console.log("Document data:", doc.data());
    } else {
        console.log("No such document!");
    }
}).catch(function(error) {
    console.log("Error getting document:", error);
});

我认为您应该更改结构数据。

结构数据应类似于db.collection('coll').doc('doc').collection('subcoll').doc('subdoc')

({Collections->doc->SubCollections->SubDoc->SubSubCollections->SubSubDoc

因此{userId}应该是docId。不是收藏集。

安全规则应为this

  match /databases/{database}/documents {

    match /users/{userId} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;

      match /settings/{setting} {
        allow read, update, delete: if request.auth.uid == userId;
        allow create: if request.auth.uid != null;
      }
  }
}

设置集合引用为db.collection('users').doc(userId).collection('settings')

如果不起作用,则应尝试基本规则集。

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