Firebase规则可确保在创建文档时获得静态值

时间:2019-03-25 19:36:47

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

当我从客户端创建项目时,我想确保它们没有篡改planlimits

service cloud.firestore {
  function isSignedIn() {
    return request.auth != null;
  }

  match /databases/{database}/documents {
    match /projects/{projectId} {
      function hasRole(rsc, role) {
        return rsc.data.users[request.auth.uid].role == role;
      }

      function userExistsInProject(rsc) {
        return (request.auth.uid) in rsc.data.users;
      }

      function projectResource() {
        return get(/databases/$(database)/documents/projects/$(projectId));
      }

      function planIsStandard(rsc) {
        return rsc.data.plan == 'standard' && rsc.data.limits.nodes == 1;
      }

      allow create: if isSignedIn() && planIsStandard(resource);
      allow read: if isSignedIn() && userExistsInProject(resource);
      allow write: if isSignedIn() && hasRole(resource, 'owner');

      match /cluster/{clusterId} {
        allow create, write: if isSignedIn() && hasRole(projectResource(), 'owner');
        allow list, read: if isSignedIn() && userExistsInProject(projectResource());
      }
    }
  }
}

planIsStandard函数不起作用。如果我包括其中任何一个条件,则不适用于以下条件:

await db.collection('projects').add({
  plan: 'standard',
  limits: {
    nodes: 1,
  },
  name,
  created: new Date(),
  owner: user.uid,
  users: {
    [user.uid]: true,
  },
});

如果我取消了projectIsStandard支票,则可以创建文档。

这似乎是一条正常规则,我看不到我在做什么错?谢谢。

1 个答案:

答案 0 :(得分:0)

如果要检查传入文档的内容,则需要使用request.resource而不是resource。后者仅查看现有文档(如果存在)。 request.resource查看新文档或对该文档的建议更改。

因此,您的规则仅查看数据库中的现有文档,而该文档永远不会应用于新创建的文档。