我在我的Firestore数据库中有一组配置文件,并且一个名为“profilePicture”的字段,该字段具有下载链接作为其值。
我正在使用云函数,并一直尝试找出如何在删除配置文件时删除profilePicture的方法。
我知道如何创建一个触发器,当删除配置文件时获取配置文件图片的下载链接,但是如何仅使用下载链接从存储中删除文件呢?
我在我的Firestore数据库中有一组配置文件,并且一个名为“profilePicture”的字段,该字段具有下载链接作为其值。
我正在使用云函数,并一直尝试找出如何在删除配置文件时删除profilePicture的方法。
我知道如何创建一个触发器,当删除配置文件时获取配置文件图片的下载链接,但是如何仅使用下载链接从存储中删除文件呢?
Firebase存储文档提供了一个可以在Storage
实例上使用的方法refFromURL(url)
。它指出url
参数可以是:
形式为:
1) gs:// URL,例如gs://bucket/files/image.png
2) 从对象元数据获取的下载URL。
基于上述(2),似乎HTTP URL也应该有效。然而,最好的做法可能是存储路径字符串,因为Firebase上的HTTP URL令牌可能会被轮换。
对于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团队可能会觉得需要改变它,因此如果格式改变,此方法可能在将来无法使用。
在Angular中,我使用以下方法通过downloadURL从Cloud Firestore中删除文件:
constructor(private storage: AngularFireStorage) {}
onDeleteAttachment(downloadURL: string) {
this.storage.storage.refFromURL(downloadURL).delete();
}
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>
</>
);
}
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;
}