我的 Firestore 数据库中有一个配置文件集合,以及一个名为“profilePicture”的字段,其值为 downloadUrl。
我正在使用云功能,并且尝试了很长时间来弄清楚如何在删除个人资料时删除个人资料图片。
我知道如何在删除个人资料时创建触发器并获取个人资料图片 downloadUrl,但如何仅使用 downloadUrl 从存储中删除文件?
firebase 存储文档提供了一种可在
refFromURL(url)
实例上使用的方法 Storage
。它指出 url
参数可以是:
表单中的 URL:
1) gs:// URL,例如 gs://bucket/files/image.png
2) 从对象元数据获取的下载 URL。
根据上面的 (2),HTTP URL 似乎也应该有效。然而,存储路径字符串可能是更好的做法,因为 Firebase 可以轮换 HTTP URL 上的令牌。
我的理解是node SDK for Cloud Storage无法将HTTP URL转换为存储桶内的文件路径。 相反,您应该将文件路径与下载 URL 一起存储在文档中。 这将使构建一个文件对象成为可能,该对象可用于在需要时删除图像。
for
admin.storage.Storage
没有内置方法用于从 url 获取引用以进行存储
但是您可以通过删除 baseUrl 并在 URL 上进行一些代码替换来从 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;
}
注意: 您必须为每个项目替换
,您可以通过打开存储中的任何图像来找到它,然后从浏览器中的 URL 从最后一个斜杠“/”的开头到结尾复制它baseUrl
例如:
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();
}
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;
}
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>
</>
);
}
我认为新的js sdk可以使用保存期间提供的完整网址进行删除
//url = "https://**url provided in downloadURL while saving**"
deleteimage(url: string){
const storage = getStorage();
var storageRef = ref(storage, url);
// console.log(storageRef.fullPath)
deleteObject(storageRef).then(() => {
// File deleted successfully
}).catch((error) => {
// Uh-oh, an error occurred!
});
}
saveImage(){
const storage = getStorage();
const storageRef = ref(storage, 'images/rivers.jpg');
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on('state_changed',
(snapshot) => {
// Observe state change events such as progress, pause, and resume
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
switch (snapshot.state) {
case 'paused':
console.log('Upload is paused');
break;
case 'running':
console.log('Upload is running');
break;
}
},
(error) => {
// Handle unsuccessful uploads
},
() => {
// Handle successful uploads on complete
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
////use this download url to delete
console.log('File available at', downloadURL);
});
}
);
}