I have a collection of profiles in my Firestore db and a field named "profilePicture" with a downloadUrl as the value.
Im using cloud functions and been trying for a long time to figure out how to delete the profilePicture when the profile is deleted.
I know how to create a trigger when the profile is deleted and get the profile picture downloadUrl, but how do I delete the file from storage with only the downloadUrl?
The firebase storage documentation provides a method refFromURL(url)
that can be used on a Storage
instance. It states the url
argument can be:
A URL in the form:
1) a gs:// URL, for example gs://bucket/files/image.png
2) a download URL taken from object metadata.
Based (2) above, it seems like an HTTP URL should also work. However it probably is better practise to store a path string, as the tokens on the HTTP URLs can get rotated by Firebase.
for admin.storage.Storage
is no build in method for get reference from url for storage
but you can extract file path from URL ,by remove baseUrl and do some code replace on URL
im create method for this task to accept url from storage project and return path
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;
}
NOTE : You must replace
baseUrl
for every project, you can find it by open any image in you storage , and copy it from URL in browser from start to end of last slash '/'
Ex :
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/
now after get path call file to delete it from storage
const storage = admin.storage();
const imagePath:string = getPathStorageFromUrl(obj.imageUrl);
storage.bucket().file(imagePath).delete().catch((err) => console.error(err));
NOTE : There is no documentation explaining the format of the URL, which implies that the Firebase team might feel the need to change it some day , mean maybe will not work in the future if format is change.
In Angular I use this to delete file from Cloud Firestore by downloadURL
constructor(private storage: AngularFireStorage) {}
onDeleteAttachment(downloadURL: string) {
this.storage.storage.refFromURL(downloadURL).delete();
}
My understanding is that the node SDK for Cloud Storage can't convert HTTP URLs into file paths within a storage bucket. Instead, you should be storing the file path along with the download URL in document. This will make it possible for to build a File object that can be used to delete the image when it's time to do so.
Mahmoud's answer need a little edit .. it works tho .. He is doing the replacements wrongly and might not work if you have nested directories or spaced filenames in your storage
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>
</>
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.