codeThinker123
codeThinker123

Reputation: 692

How to delete a Firebase Storage file with flutter?

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.

See screen shot

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?

Found Temporary solution

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

Answers (11)

jbryanh
jbryanh

Reputation: 2013

With the latest breaking changes, this is the following straightforward method I've used.

  1. 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
    
  2. import the package as follows:

    import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
    
  3. 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

M.Adnan Ijaz
M.Adnan Ijaz

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

Frank van Puffelen
Frank van Puffelen

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

powermouse
powermouse

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

awaik
awaik

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

M.Adnan Ijaz
M.Adnan Ijaz

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

Feisal  Aswad
Feisal Aswad

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

Janaka
Janaka

Reputation: 2795

 if (post.imageURL != null) {
    StorageReference photoRef =
        await FirebaseStorage.instance.getReferenceFromUrl(post.imageURL);

    await photoRef.delete();
  }

Upvotes: 2

harlandgomez
harlandgomez

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

leoelstin
leoelstin

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

Abdel Hameed
Abdel Hameed

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

Related Questions