【问题标题】:Error in snapshot listener: FirebaseError: Missing or insufficient permissions快照侦听器中的错误:FirebaseError:缺少权限或权限不足
【发布时间】:2022-08-06 23:17:26
【问题描述】:

我在 Google Firebase 上有一个 Firestore 数据库,里面有“村庄”集合。 我想限制特定用户的每个文档的读/写功能,并将他们的 uuid 作为文档键。

我已将规则添加到 Firestore 中的“规则”选项卡,但是当我尝试获取数据时,我收到一条错误消息,提示我没有对 Firestore 的权限...

这是我的规则:

 rules_version = \'2\';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /village/{villageId} {
            allow read, write: if request.auth != null && request.auth.uid == villageId;
            }
      }
    }

如果我从 Firestore 中删除我的规则,这是成功返回数据的代码 sn-p:

 useEffect(() => {
    const collectionRef = collection(db, \"village\");
    const q = query(collectionRef, orderBy(\"timestamp\", \"desc\"));
    const unsubscribe = onSnapshot(q, (querySnapshot: any) => {
      setVillage(
        querySnapshot.docs.map((doc) => ({
          ...doc.data(),
          id: doc.id,
          timestamp: doc.data().timestamp?.toDate().getTime(),
        }))
      );
    });
    return unsubscribe;
  }, []);

这是console.log

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


    【解决方案1】:

    您当前的查询是请求所有村庄,并按其时间戳对其进行排序。因为您的用户只能访问他们自己的村庄,所以您需要将查询更改为仅针对他们有权访问的内容(请记住 Firestore 安全规则are not filters)。

    要更新您的代码以使用您定义的规则,您需要从查询所有村庄切换到仅查询他们的村庄。

    const currentUser = ...;
    
    useEffect(
      () => {
        if (!currentUser) return; // signed out
    
        const villageDocRef = doc(db, "village", auth.currentUser.uid);
    
        return onSnapshot(
          villageDocRef,
          {
            next: (docSnapshot) => { // don't use the any type
              if (!docSnapshot.exists()) { // don't forget to handle missing data
                return setVillage(null);
              }
              docData = docSnapshot.data();
              setVillage({
                ...docData,
                id: docSnapshot.id,
                timestamp: docData.timestamp?.toMillis() // shorter than .toDate().getTime()
              });
            },
            error: (err) => {
              // TODO: Handle Firestore errors
              console.error('Failed to get village data ', err);
              setVillage(null);
            }
          }
        );
      },
      [currentUser] // rerun when user changes
    );
    

    【讨论】:

    • 所以计划是创建一个只查询特定文档的查询,然后我还需要编写 Firestore 规则来保护自己?
    • @florjank 因为 Firestore 是一个无服务器数据库,所以安全规则是防止用户读取/写入不属于他们的数据的方式。当您编写查询时,如果它会返回用户无权访问的任何文档,则整个查询将被拒绝,并出现权限不足错误。因此,您调整查询,以便用户可以访问与您的查询匹配的任何文档。您可以将查询修改为 query(collectionRef, orderBy(documentId(), "desc"), orderBy("timestamp", "desc"), where(documentId(), "==", currentUser.uid)),但使用 doc ref 更简单。
    【解决方案2】:

    可能对某人有所帮助,在我的情况下发生了同样的错误,因为在 Firestore 规则中我有 request.time < timestamp.date(2022, 8, 6); 将日期更改为以后的时间点解决了我的问题。

    【讨论】:

      猜你喜欢
      • 2021-06-20
      • 2021-03-10
      • 2022-06-10
      • 2023-01-10
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2021-12-01
      相关资源
      最近更新 更多