快照侦听器中的错误:FirebaseError:丢失或不足的权限

发布于 2025-02-01 22:53:41 字数 1450 浏览 5 评论 0 原文

我在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中删除我的规则,则成功返回数据:

 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

I have a Firestore database on Google Firebase with "village" collection inside of it.
I want to limit read/write functionality for each document for specific user with their uuid as the document key.

I have added the rule to the "Rules" tab in Firestore, but I'm when I'm trying to fetch data I get an error saying that I don't have permisions to the Firestore...

Village collection
Document/user uuid

This is my rule:

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

This is the code snippet which returns data successfully if I remove my rule from Firestore:

 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;
  }, []);

This is the console.log
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挥剑断情 2025-02-08 22:53:41

您当前的查询要求所有村庄,并通过时间戳订购。因为您的用户只能访问自己的村庄,所以您需要更改查询以仅针对他们有权访问的东西(请记住,Firestore安全规则不是过滤)。

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

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
);

Your current query is requesting all villages, and ordering them by their timestamp. Because your user can only access their own village, you need to change your query to only target what they have access to (remember that Firestore Security Rules are not filters).

To update your code to work with the rules you defined, you need to switch from a query of all villages, to just their village.

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
);
止于盛夏 2025-02-08 22:53:41

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

May it help someone, in my case the same error occurred because in Firestore rules I had request.time < timestamp.date(2022, 8, 6); Changing the date to a later point in time solved my issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文