【问题标题】:Delete a file from firebase storage using download url with Cloud Functions使用 Cloud Functions 的下载 URL 从 Firebase 存储中删除文件
【发布时间】:2018-10-01 09:18:19
【问题描述】:

我的 Firestore 数据库中有一组配置文件和一个名为“profilePicture”的字段,其值为 downloadUrl。

我正在使用云功能,并且一直在尝试弄清楚如何在删除配置文件时删除配置文件图片。

我知道如何在删除配置文件时创建触发器并获取配置文件图片 downloadUrl,但是如何仅使用 downloadUrl 从存储中删除文件?

【问题讨论】:

  • 你是如何生成下载地址的?
  • @DougStevenson 我刚刚在使用 swift 将图片存储在设备上时从元数据中检索到它。

标签: node.js firebase google-cloud-storage google-cloud-firestore


【解决方案1】:

firebase storage documentation 提供了一个方法refFromURL(url),可以在Storage 实例上使用。它指出url 参数可以是:

表单中的 URL:

1) 一个 gs:// 网址,例如 gs://bucket/files/image.png

2) 从对象元数据中获取的下载 URL。

根据上面的 (2),似乎 HTTP URL 也应该可以工作。但是,存储路径字符串可能是更好的做法,因为 Firebase 可以轮换 HTTP URL 上的令牌。

【讨论】:

    【解决方案2】:

    admin.storage.Storage 没有内置方法从 url 获取引用以进行存储

    但您可以从 URL 中提取文件路径,方法是删除 baseUrl 并对 URL 进行一些代码替换

    我为此任务创建方法以接受来自存储项目的 url 并返回路径

    function getPathStorageFromUrl(url:String){
    
        const baseUrl = "https://firebasestorage.googleapis.com/v0/b/project-80505.appspot.com/o/";
    
        let imagePath:string = url.replace(baseUrl,"");
    
        const indexOfEndPath = imagePath.indexOf("?");
    
        imagePath = imagePath.substring(0,indexOfEndPath);
        
         imagePath = imagePath.replace("%2F","/");
        
     
        return imagePath;
    }
    

    注意:您必须为每个项目替换baseUrl,您可以通过打开存储中的任何图像来找到它,并将其从浏览器中的URL复制到最后一个斜杠'/ '

    例如:

    Some image link on my storage : 
    https://firebasestorage.googleapis.com/v0/b/project-80505.appspot.com/o/RequestsScreenshot%2F-M6CA-2bG2aP_WwOF-dR__1i5056O335?alt=media&token=d000fab7
    
    the base URL will be 
    https://firebasestorage.googleapis.com/v0/b/project-80505.appspot.com/o/ 
    

    现在在获取路径调用文件后将其从存储中删除

    const storage = admin.storage();
    
    const imagePath:string = getPathStorageFromUrl(obj.imageUrl);
    
    storage.bucket().file(imagePath).delete().catch((err) => console.error(err));
    

    注意:没有说明 URL 格式的文档, 这意味着 Firebase 团队可能觉得有必要改变它 总有一天,如果格式发生变化,意味着将来可能无法使用。

    【讨论】:

      【解决方案3】:

      我的理解是node SDK for Cloud Storage 无法将 HTTP URL 转换为存储桶内的文件路径。相反,您应该将文件路径与下载 URL 一起存储在文档中。这将使构建一个 File 对象成为可能,该对象可用于在需要时删除图像。

      【讨论】:

      • 这就是我的想法。我将采用您的解决方案,因此我会将您的答案标记为正确。
      • 但您可以从 url 中提取路径文件,请参阅下面的答案
      • @MahmoudAbuElheja Firebase Storage 不保证该 URL 的格式。如果你依赖它的格式,你的代码将来可能会中断。这是您必须承担的风险。
      • @DougStevenson 感谢您通知我,但您确定因为我在存储上的多文件上测试了这种方法并且工作正常! ,那么这可能不适用于什么情况?
      • @MahmoudAbuElheja 仅仅因为某些东西今天有效,这并不意味着将来会有效。没有解释 URL 格式的文档,这意味着 Firebase 团队可能会觉得有必要在某一天更改它。
      【解决方案4】:

      在 Angular 中,我使用它通过 downloadURL 从 Cloud Firestore 中删除文件

      constructor(private storage: AngularFireStorage) {}
      
      onDeleteAttachment(downloadURL: string) {
        this.storage.storage.refFromURL(downloadURL).delete();
      }
      

      【讨论】:

        【解决方案5】:

        confing.js

        import firebase from 'firebase/app'
        import "firebase/firestore";
        import "firebase/storage";
        
        const firebaseConfig = {
                    apiKey: "XXXX",
                    authDomain: "XXXXX.firebaseapp.com",
                    databaseURL: "https://XXXX-app-web.firebaseio.com",
                    projectId: "XXXX",
                    storageBucket: "XXXX-app-web.appspot.com",
                    messagingSenderId: "XXXXXX",
                    appId: "1:XXX:web:XXXX",
                    measurementId: "G-XXXX"
        };
        firebase.initializeApp(firebaseConfig);
        export const firestore = firebase.firestore();
        export const storageRef = firebase.storage();
        
        export default firebase;
        
        

        Button.js

        import React from 'react';
        import {firestore,storageRef} from './Config';
        
        function removeFile(id,downloadUrl) {
          const storageRefa = storageRef.refFromURL(downloadUrl);
        
          storageRefa.delete().then(() => {
            firestore.collection("All_Files").doc(id).delete().then((response) => {
              console.log('delete response', response)
            }).catch((error) => {
              console.log('delete error', error)
            })
          }).catch((error) => {
            console.log('delete error', error)
          });
        }
        export default function MediaCard(props) {
          return (
            <>
                   <Button
                      onClick={() =>{
                        removeFile(props.ID,props.downloadUrl)
                      }}
                      variant="contained"
                      color="secondary"
                  >
                    Delete
                  </Button>
            </>
          );
        }
        

        【讨论】:

        • refFromURL 存在于 Web SDK 中,而不是问题所问的云函数 SDK 中。
        【解决方案6】:

        Mahmoud 的回答需要稍作修改 .. 它可以工作 .. 他错误地进行了替换,如果您的存储中有嵌套目录或间隔文件名,则可能无法正常工作

        getPathStorageFromUrl(url:String){
        
                const baseUrl = "https://firebasestorage.googleapis.com/v0/b/project-80505.appspot.com/o/";
            
                let imagePath:string = url.replace(baseUrl,"");
            
                const indexOfEndPath = imagePath.indexOf("?");
            
                imagePath = imagePath.substring(0,indexOfEndPath);
                
                imagePath = imagePath.replace(/%2F/g,"/");
                
                imagePath = imagePath.replace(/%20/g," ");
             
                return imagePath;
            }

        【讨论】:

          猜你喜欢
          • 2021-11-04
          • 2018-02-28
          • 1970-01-01
          • 2018-05-02
          • 2018-01-27
          • 2020-01-25
          • 2017-09-26
          • 2020-01-12
          • 2019-03-23
          相关资源
          最近更新 更多