为啥我的 Firebase 安全规则没有按预期工作?

Posted

技术标签:

【中文标题】为啥我的 Firebase 安全规则没有按预期工作?【英文标题】:Why is my firebase security rules not working as expected?为什么我的 Firebase 安全规则没有按预期工作? 【发布时间】:2021-07-14 16:14:57 【问题描述】:

我想允许用户在我的应用上编辑他们的帖子。如果他们的 uid 与存储中文件夹的名称匹配,他们就可以编辑他们的帖子。

这是我的 Firebase 存储的安全规则:

它说如果我愿意,我可以删除图像(users/gafspL9sdVSOXVkxYNlqzxyDbvG2/listingPhotos/lXOxKS1N8dFefzai5H2B/R158bed9819e4fccf7e18a5eeeaf79c6b.png)

然后,当我尝试编辑所述列表时:

我收到 403 错误。用户未授权,实际上它在 GET 函数中抛出此错误,甚至在删除部分。

正如你在上面看到的,我目前已经登录并且我的 uid 是正确的。

错误:(xhrio_network.ts:70 GET mydomainname?prefix=users%2FgafspL9sdVSOXVkxYNlqzxyDbvG2%2FlistingPhotos%2FlXOxKS1N8dFefzai5H2B%2F&delimiter=%2F 403)

这是我要访问的文件夹:

我的文件夹设置:mybucket/users/userUID/listingPhotos/listingID/picture.jpg

你们有什么想法吗?可能我的代码行不正确,但是模拟说没有问题,所以我有点糊涂了。

谢谢!

编辑

当用户想要编辑他们的列表时,我会更新存储在 firestore 中的列表详细信息,然后删除存储在 firebase 存储文件夹中的所有照片,然后上传新的一批照片。

我在这里更新列表详细信息并删除现有照片:

 function editListingData() 
    setLoading("loading");
    db.collection("listings")
      .doc(listingID)
      .set(
        
          title: title,
          category: category,
          condition: condition,
          description: description,
          price: price,
          sellingFormat: sellingDetails,
          shippingPrice: shippingPrice,
          listingPhotos: [],
        ,
         merge: true 
      )
      .then(() => 
        const storageRef = firebase
          .storage()
          .ref()
          .child(
            `users/` +
            auth.currentUser.uid +
            `/listingPhotos/` +
            listingID +
            `/`
          );
        storageRef.listAll().then((listResults) => 
          const promises = listResults.items.map((item) => 
            console.log("deleting item: ", item.name)
            return item.delete();
          )
          Promise.all(promises).then(
            onUploadSubmission()
          ).catch((error => console.log("error deleteing files", error)));
        );
      )
      .then(() => 
        setLoading("complete");
        setTimeout(() => 
          history.push("/l/" + listingID)
        , 2000);
      )
      .catch((error) => 
        console.log("firebase error: " + error);
        setLoading("error");
      );
  

这是我上传新照片的地方,然后将它们的下载 URL 放入 firestore 文档中,以便以后轻松获取它们:

  function onUploadSubmission() 
    if (photos != []) 
      const promises = [];
      var listingREF = db.collection("listings").doc(listingID);
      photos.forEach((photo, index) => 
        if (photo.fileType.includes('image')) 
          console.log("current photo to upload: ", photo, "index: ", index)
          const uploadTask = firebase
            .storage()
            .ref()
            .child(
              `users/` +
              auth.currentUser.uid +
              `/listingPhotos/` +
              listingID +
              `/$"photo" + index`
            )
            .put(photo.file);
          promises.push(uploadTask);
          uploadTask.on(
            firebase.storage.TaskEvent.STATE_CHANGED,
            (snapshot) => 
              const progress =
                (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
              if (snapshot.state === firebase.storage.TaskState.RUNNING) 
                console.log(`Progress: $progress%`);
              
            ,
            (error) => console.log(error.code),
            async () => 
              const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
              listingREF.update(
                listingPhotos: firebase.firestore.FieldValue.arrayUnion(
                  
                    url: downloadURL,
                    index: index
                  
                ),
              );
            
          );
        
      );
      Promise.all(promises)
        .then(() => setCreatedListing(false))
        .catch((err) => console.log(err.code));
     else 

    
  

编辑 2

所以我想要实现的是:

用户可以编辑自己的照片(列表照片和头像)

为此,他们将:

    选择他们的新照片。 当他们点击提交时,firebase 将删除当前存储在 firebase 存储中的照片。 然后它将上传用户之前选择的新照片。 然后将下载 URL 复制到 Firestore 中的列表文档中,以便我们以后轻松查看它们

存储的安全规则是:

任何人都可以阅读用户照片(类似于 eBay,您可以看到 无论您是否登录,都会列出照片) 用户只能写入(删除、更新、创建)自己的文件夹。每个文件夹都以用户 UID 命名。只有当前登录的用户 UID 与存储中文件夹的名称匹配时,他们才能访问这些文件夹。

【问题讨论】:

有什么要求?您不希望用户删除他们的图片吗? 当用户更新他们的列表时,它会删除列表中当前的图片,然后上传新的图片集。所以理论上,用户可以删除自己的照片 您的应用程序是如何工作的令人困惑,因为当用户添加新图像时,旧图像不会被删除。你能列出你的要求吗? 确定,让我更新我的帖子以显示我在做什么 @Dharmaraj 刚刚添加了我的代码 【参考方案1】:

您在 get() 方法上收到的错误是由于该位置中的规则缺乏对该目录的读取权限。 规则从上到下级联,虽然你有上面的阅读,但这仅适用于指定路径users/userUID

一旦解决了,我们就可以继续调试了。

【讨论】:

以上是关于为啥我的 Firebase 安全规则没有按预期工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的替换没有按预期工作[重复]

为啥我的查询没有按预期工作?

为啥我的 javascript 代码没有按预期工作

为啥我的依赖属性绑定没有按预期工作?

为啥我的 Laravel 一对一关系没有按预期工作?

为啥我的搜索功能没有按预期工作,我该如何解决?