使用 Cloud Functions 的下载 URL 从 Firebase 存储中删除文件

Posted

技术标签:

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

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

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

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

【问题讨论】:

你是如何生成下载地址的? @DougStevenson 我刚刚在使用 swift 将图片存储在设备上时从元数据中检索到它。 This is link answer the Question 【参考方案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;
    

【讨论】:

以上是关于使用 Cloud Functions 的下载 URL 从 Firebase 存储中删除文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Google Python Client for Cloud Functions 获取 Google Cloud Functions 列表?

在 Cloud Functions 中使用 Cloud Firestore 数据

使用 Cloud Scheduler 触发 Cloud Functions 的 HTTP

Cloud Tasks + Cloud Functions - 重复执行

如何使用 Google Cloud SDK 列出所有 Cloud Functions?

如何从 Cloud Functions 连接 Google Cloud SQL?