Error in snapshot listener: FirebaseError: Missing or insufficient permissions

Error in snapshot listener: FirebaseError: Missing or insufficient permissions

我在 Google Firebase 上有一个 Firestore 数据库,其中包含“village”集合。 我想限制 read/write 特定用户的每个文档的功能,并将他们的 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 中删除我的规则,returns 数据成功的代码片段:

 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

您当前的查询是请求所有村庄,并按时间戳对它们进行排序。因为您的用户只能访问他们自己的村庄,所以您需要更改查询以仅针对他们有权访问的内容(请记住 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
);