Firebase Firestore安全规则变量未使用

时间:2019-02-18 06:12:48

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

Firestore的编写规则似乎自定义变量无效。 有谁知道为什么或已经看到类似的行为? 使用下面的代码,虽然uid在admin数组中,但我拒绝了访问。

service cloud.firestore {
      match /databases/{database}/documents {
        match /conferences/{confid} {
          allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confid)).data.admin;
        }
      }
    }

模拟器出现以下错误:

使用不存在资源的路径调用的函数[get]:/ databases /%28default%29/29 / documents / conferences /%7Bconfid%7D

也在真实的设备上测试此操作,但我拒绝了访问。

但是,如果我像下面那样使用文档的ID,它可以工作并且可以访问。

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confid} {
      allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/ySWLb8NSTj9sur6n2CbS).data.admin;
    }
  }
}

显然,我无法为每个ID进行硬编码。

更新

除了在支持下记录该案例,我还进行了一些进一步的测试。 模拟器现在在下面授予访问权限。

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
        }
  }
}

Simulator

作为参考,我使用以下内容从Web应用程序中查询:

db.collection("conferences")
  .get()
  .then(query => {
    console.log("SUCCESS!!!")
    query.forEach(function(doc) {
      // doc.data() is never undefined for query doc snapshots
      console.log(doc.id, " => ", doc.data());
    });
  }).catch((e) => {
    console.log(e)
  })

这是来自浏览器的日志:

FirebaseError:缺少权限或权限不足。     在新的FirestoreError(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:352:28)     在JsonProtoSerializer.fromRpcStatus(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:5649:16)中     在JsonProtoSerializer.fromWatchChange(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:6146:44)     在PersistentListenStream.onMessage(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:14350:43)     在评估时(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14279:30)     在评估时(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14319:28)     在评估时(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:7411:20)

我正在使用最新的Firebase软件包5.8.3。

如果我将上述规则更改为类似下面的简单内容,只要我以用户身份登录,它就可以访问:

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

这甚至让我感到困惑。这是因为规则更复杂,验证时间太长,并且拒绝回访吗?

Update-2

通过Flutter在移动应用中对此进行了快速测试。结果相同。此规则集拒绝访问。

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
        }
  }
}

Firestore

2 个答案:

答案 0 :(得分:0)

我认为我的问题是查询的安全规则不匹配。如果只访问一个特定的文档,它将起作用,但是,如果您查询集合中的多个文档,则会被安全规则阻止。 我有两个选择。重组我的数据,以便一个文档可以容纳我需要的所有数据,或者重新设计安全规则以匹配查询的数据。 最后,我在每个文档上附加了一个标识符,例如UID,以确保查询与安全规则匹配。

答案 1 :(得分:0)

一种解决方案是将具有权限的用户放到会议文档的数组中, 所以request.resource.data.permissions

所以,代替这个:

get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users

使用此:

request.resource.data.permissions

这不能解决get()问题,但可以消除对get()通话的需求,这样可以节省15%或更多的配额。