Reputation: 692
I'm new to both Flutter and Firebase, so bear with me on this one.
I am trying to delete a File in my Firebase Storage using the file Url.
I have the full Url of the file and remove all characters excluding the file path.
Then I try to delete the file. From following other answers on here I use the command;
FirebaseStorage.instance.ref().child(filePath).delete()
Below is my code;
static void deleteFireBaseStorageItem(String fileUrl){
String filePath = 'https://firebasestorage.googleapis.com/v0/b/dial-i-2345.appspot.com/o/default_images%2Fuser.png?alt=media&token=c2ccceec-8d24-42fe-b5c0-c987733ac8ae'
.replaceAll(new
RegExp(r'https://firebasestorage.googleapis.com/v0/b/dial-in-2345.appspot.com/o/'), '');
FirebaseStorage.instance.ref().child(filePath).delete().then((_) => print('Successfully deleted $filePath storage item' ));
}
The problem is the file never gets deleted.
I think I have tracked down where the problem is.
In the .delete()
method there is a required 'app' and 'storageBucket' value.
When I run this function the values are null.
I find this confusing because in the same file i see this;
/// The [FirebaseApp] instance to which this [FirebaseStorage] belongs.
///
/// If null, the default [FirebaseApp] is used.
final FirebaseApp app;
/// The Google Cloud Storage bucket to which this [FirebaseStorage] belongs.
///
/// If null, the storage bucket of the specified [FirebaseApp] is used.
final String storageBucket;enter code here
From the documentation I can see maybe I need to use the 'Firebase core' plugin to make the app which links the bucket to that database. But there is not much specific to Dart & flutter.
Does anyone have any experience with this?
So there is not a method to convert the Url to a storage reference at the moment. Hopefully it will come out in a Firebase update.
Here was my hack
static void deleteFireBaseStorageItem(String fileUrl){
String filePath = fileUrl
.replaceAll(new
RegExp(r'https://firebasestorage.googleapis.com/v0/b/dial-in-2345.appspot.com/o/'), '');
filePath = filePath.replaceAll(new RegExp(r'%2F'), '/');
filePath = filePath.replaceAll(new RegExp(r'(\?alt).*'), '');
StorageReference storageReferance = FirebaseStorage.instance.ref();
storageReferance.child(filePath).delete().then((_) => print('Successfully deleted $filePath storage item' ));
}
I know.... i know....
Ps 'dial-in-2345.appspot.com' is relevant to my app and you would need to change it.
Upvotes: 30
Views: 24086
Reputation: 2013
With the latest breaking changes, this is the following straightforward method I've used.
Import the latest firebase_storage
and all the other dependent updates it will require to your pubspec.yaml
. currently this is the following for firebase_storage:
dependencies:
firebase_storage: ^7.0.0
import the package as follows:
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
Finally, within a try catch, you can do the following:
try
{
await firebase_storage.FirebaseStorage.instance.ref('/images/something.jpg').delete();
} catch (e) {
debugPrint('Error deleting $yourReference: $e');
}
Upvotes: 0
Reputation: 141
August, 10 2021
If you want to delete image from firebase you must have url of that image just like :
https://firebasestorage.googleapis.com/v0/b/ecommerce-c962d.appspot.com/o/images%2F2021-08-03T11%3A10%3A27.616369?alt=media&token=5310a745-9533-47ef-8de1-db876933ff6f Then you just have to pass that url inside of:
Reference photoRef =await FirebaseStorage.instance.refFromURL(imageUrl);
await photoRef.delete().then((value) {
print('deleted Successfully');
});
Upvotes: 2
Reputation: 598765
Update (2021-05-22):
FirebaseStorage.instance.refFromURL(url).delete()
should be used now.
getReferenceFromUrl
that was suggested earlier seems to be gone from the API.
Update (2019-08-03):
According to this PR there is now a getReferenceFromUrl
method in FlutterFire that allows looking up a storage reference by its download URL.
Previous answer:
On Android you can call getReferenceForUrl()
to get a StorageReference
from a download URL, and a similar method exists on iOS.
But I can't find a corresponding method in the FlutterFire reference docs. This unfortunately means that there is no way to map from a download URL back to a StorageReference
in Flutter.
This sounds like an omission, so I recommend casting your +1 on this feature request.
For the moment this means you'll need to have the relative path to the file in Cloud Storage to be able to delete it from Flutter. With that path, your current code would work.
Upvotes: 36
Reputation: 31
3. 3. 2021
I am not sure how was it in the past (because I am quite new to Flutter and Firebase), but currently it is quite simple. Suppose you want to delete an image from Firebase Storage. In order to do that you will write the following method:
import 'package:firebase_storage/firebase_storage.dart';
//firebase Storage reference
final _storage = FirebaseStorage.instanceFor(
bucket: [your bucket address]);
Future<void> deleteImageFromDB(String imageUrl) async {
var photo = _storage.refFromURL(imageUrl);
await photo.delete();
}
Upvotes: 2
Reputation: 12287
=== December 2020 ===
Great thank for the answers, this is just an update, because old ways led my app to crash.
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path/path.dart' as Path;
String fileUrl =Uri.decodeFull(Path.basename(i)).replaceAll(RegExp(r'(\?alt).*'), '');
StorageReference ref = FirebaseStorage.instance.ref().child(fileUrl);
await ref.delete();
Upvotes: 2
Reputation: 141
You have to create instance of StorageReference storageReference;
then initialize it like
storageReference = await FirebaseStorage.instance
.getReferenceFromUrl('photoUrl');
you must have photoUrl so that storageReference is pointed towards right image. Then just delete it like
storageReference.delete();
All done.
Upvotes: 0
Reputation: 455
This function work very well for firebase storage link
static Future<bool> deleteFileFromFirebaseByUrl(String urlFile) async {
String fileName = urlFile.replaceAll("/o/", "*");
fileName = fileName.replaceAll("?", "*");
fileName = fileName.split("*")[1];
print(fileName);
StorageReference storageReferance = FirebaseStorage.instance.ref();
storageReferance
.child(fileName)
.delete()
.then((_) => print('Successfully deleted $fileName storage item')); }
Upvotes: 0
Reputation: 2795
if (post.imageURL != null) {
StorageReference photoRef =
await FirebaseStorage.instance.getReferenceFromUrl(post.imageURL);
await photoRef.delete();
}
Upvotes: 2
Reputation: 569
I have implemented a cleaner code but same as @earyhe, which is using Uri.decodeFull()
and Path.basename()
. Tried and it worked.
import 'package:path/path.dart' as Path;
Future<void> deleteImage(String imageFileUrl) async {
var fileUrl = Uri.decodeFull(Path.basename(imageFileUrl)).replaceAll(new RegExp(r'(\?alt).*'), '');
final StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child(fileUrl);
await firebaseStorageRef.delete();
}
Upvotes: 3
Reputation: 3258
With respect to @Frank van Puffelen answer here is the code snippet to delete the file from Firebase storage with reference to the URL
if (oldUrl != null) {
var fileUrl = Uri.decodeFull(Path.basename(oldUrl))
.replaceAll(new RegExp(r'(\?alt).*'), '');
StorageReference photoRef = await FirebaseStorage.instance
.ref()
.getStorage()
.getReferenceFromUrl(oldUrl);
try {
await photoRef.delete();
} catch (e) {}
}
Complete method
Future<UserItem> uploadUserImage(String filePath, {String oldUrl}) async {
if (oldUrl != null) {
var fileUrl = Uri.decodeFull(Path.basename(oldUrl))
.replaceAll(new RegExp(r'(\?alt).*'), '');
StorageReference photoRef = await FirebaseStorage.instance
.ref()
.getStorage()
.getReferenceFromUrl(oldUrl);
try {
await photoRef.delete();
} catch (e) {}
}
Im.Image image = Im.decodeImage(File(filePath).readAsBytesSync());
// todo cleanup string formation
final StorageReference storageReference =
FirebaseStorage().ref().child('user_images').child(
DateTime.now().millisecondsSinceEpoch.toString() +
'.' +
filePath.split(".")[1],
);
final StorageUploadTask uploadTask = storageReference.putFile(
File(filePath),
);
/// wait for upload to complete
await uploadTask.onComplete;
/// get the uploaded items url
String url = await (storageReference.getDownloadURL());
/// add the pic to FireStore Instance
FirebaseUser user = await FirebaseAuth.instance.currentUser();
String token = user.uid;
/// adds the item to the corresponding token path
await _fireStore
.document('$token')
.setData({'userImage': url}, merge: true);
return await getUserData();
}
Upvotes: 2
Reputation: 39
change filePath to
String filePath = 'https://firebasestorage.googleapis.com/v0/b/dial-in-21c50.appspot.com/o/default_images%2Fuser.png?alt=media&token=c2ccceec-8d24-42fe-b5c0-c987733ac8ae'
.replaceAll(new
RegExp(r'https://firebasestorage.googleapis.com/v0/b/dial-in-21c50.appspot.com/o/default_images%2F'), '').split('?')[0];
FirebaseStorage.instance.ref().child(filePath).delete().then((_) => print('Successfully deleted $filePath storage item' ));
Upvotes: 4