首页 > 解决方案 > 使用 onSnapshot 函数时忽略 Cloud Firestore 安全规则

问题描述

使用 onSnapShot 时,我的安全角色被忽略 - 我正在获取集合中的所有文档,而不仅仅是用户对象。

角色:

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

match /story/{mid} {

  function memberOf() {
    return resource.data.creator && request.auth.uid == resource.data.creator;
  }
  allow list: if request.query.limit <= 1000 &&
                 memberOf();
  allow get,read : if memberOf();
  allow write: if request.auth.uid == resource.data.creator;
  }
 }
}

我的代码在 Android 上的 react-native-firebase 中: "react-native-firebase": "^4.3.8", "com.google.firebase:firebase-firestore:17.1.0"

导演: this.ref = firebase.firestore().collection('story');

componentDidMount() {
    this.unsubscribeDate = this.ref.onSnapshot(this.onCollectionUpdate);
}

componentWillUnmount() {
    this.unsubscribeDate();
}

onCollectionUpdate = querySnapshot => {
    //console.log('onCollectionUpdate', querySnapshot);
    querySnapshot.forEach(doc => {
        const { title, complete } = doc.data();
        console.log('onCollectionUpdate doc', title);
    });
};

参考文档: 基于角色的访问 角色查询

标签: javascriptfirebasegoogle-cloud-firestorefirebase-securityreact-native-firebase

解决方案


这种行为是一个错误。我得到了同样的结果,使用带有 PWA 的 javascript。

我正在做测试,我注意到在 Firestore 中使用持久性时会出现问题。使用 onSnapshot 时,启动它时会执行 2 次,如果我停用 firestore 的持久性,答案是空的,正如预期的那样,但启用持久性后会显示缓存的结果,然后执行 onSnapshot 事件的更新,但由于谷歌控制台中的规则拒绝读取,因此它不会通过事件(onCollectionUpdate)更新结果,因此您正在读取不应显示的数据。

当之前缓存中有数据时会发生这种情况,如果是第一次在设备中使用应用程序,则该规则完美运行,因为之前缓存中没有数据。我认为这种行为是一个错误,因为即使使用缓存它也应该遵守规则,因为它知道它试图限制文档的读取。

要在 onSnapshot 上打印错误:

componentDidMount() {
    this.unsubscribeDate = this.ref.onSnapshot(this.onCollectionUpdate, this.onErrorUpdate);
}

onErrorUpdate = error => {
    console.log(error);
};


推荐阅读