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

9

我在我的Firestore数据库中有一组配置文件,并且一个名为“profilePicture”的字段,该字段具有下载链接作为其值。

我正在使用云函数,并一直尝试找出如何在删除配置文件时删除profilePicture的方法。

我知道如何创建一个触发器,当删除配置文件时获取配置文件图片的下载链接,但是如何仅使用下载链接从存储中删除文件呢?


你是如何生成下载链接的? - Doug Stevenson
@DougStevenson 我刚刚使用 Swift 在设备上存储图片时,从元数据中检索到了它。 - user3116871
这是一个指向stackoverflow上回答问题的链接,无法直接翻译。请提供具体的问题和需要翻译的内容。 - Meet Bhavsar
6个回答

15

Firebase存储文档提供了一个可以在Storage实例上使用的方法refFromURL(url)。它指出url参数可以是:

形式为:

1) gs:// URL,例如gs://bucket/files/image.png

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

基于上述(2),似乎HTTP URL也应该有效。然而,最好的做法可能是存储路径字符串,因为Firebase上的HTTP URL令牌可能会被轮换。


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

我也是这么想的。我会采用你的解决方案,将你的答案标记为正确。 - user3116871
但是你可以从URL中提取路径文件,可以参考我下面的答案。 - Mahmoud Abu Alheja
Firebase存储不保证URL的格式。如果您依赖于其格式,您的代码可能会在未来出现问题。这是您必须承担的风险。 - Doug Stevenson
@DougStevenson谢谢你提醒我,但你确定吗?因为我在存储的多个文件上测试了这种方法,它可以正常工作!那么可能出现问题的情况是什么? - Mahmoud Abu Alheja
2
@MahmoudAbuElheja 只因为某个东西“今天工作了”,并不意味着它“将来也能工作”。没有文档说明URL的格式,这意味着Firebase团队可能会感到需要在未来更改它。 - Doug Stevenson

10

对于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团队可能会觉得需要改变它,因此如果格式改变,此方法可能在将来无法使用。


9

在Angular中,我使用以下方法通过downloadURL从Cloud Firestore中删除文件:

constructor(private storage: AngularFireStorage) {}

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

在 Kotlin 中有一个类似的方法 storageRef.getReferenceFromUrl(url),你的回答帮助我找到了它。谢谢。 - Mark Perry

1

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,这也是问题所询问的。 - Rodrigo Amaral

1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接