【问题标题】:How to delete a Firebase Storage file with flutter?如何使用颤振删除 Firebase 存储文件?
【发布时间】:2019-06-07 18:38:03
【问题描述】:

我是 Flutter 和 Firebase 的新手,所以请耐心等待。

我正在尝试使用文件 Url 删除 Firebase 存储中的文件。

我拥有文件的完整 URL,并删除了文件路径以外的所有字符。

然后我尝试删除该文件。从这里的其他答案中,我使用命令; FirebaseStorage.instance.ref().child(filePath).delete()

下面是我的代码;

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' ));

}

问题是文件永远不会被删除。

我想我已经找到了问题所在。

.delete() 方法中有一个必需的“app”和“storageBucket”值。

当我运行这个函数时,值是空的。

我觉得这很混乱,因为我在同一个文件中看到了这个;

/// 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

从文档中我可以看到,我可能需要使用“Firebase 核心”插件来制作将存储桶链接到该数据库的应用程序。但是 Dart 和 Flutter 并没有什么特别之处。

有人有这方面的经验吗?

找到临时解决方案

所以目前还没有将 Url 转换为存储引用的方法。希望它会在 Firebase 更新中发布。

这是我的秘诀

 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' ));

}

我知道……我知道……

Ps 'dial-in-2345.appspot.com' 与我的应用相关,您需要更改它。

【问题讨论】:

  • 这些值通常是从您在此设置步骤中包含在应用程序中的配置文件/数据中读取的:firebase.google.com/docs/flutter/…
  • 谢谢弗兰克。我运行了这个设置,我假设大部分数据都在我安装的 'google-services.json' 和 'GoogleService-Info.plist' 文件中。我可以保存文件没有问题。似乎只是在删除它们时。
  • 嗯.. 使用完全相同的配置。啊,等等,我知道发生了什么事。您将下载 URL 传递到 child,这将不起作用。让我找到可以获取下载 URL 并将其转换为正确的StorageReference 的正确方法。
  • @earyhe,您尝试删除图像文件 (png) 是否正确?也许您的图像文件的路径是"o/default_images/user.png"
  • 非常感谢提供临时解决方案,我被困了两个星期,如果不是你的解决方案,我只好等到期待已久的功能出现了。

标签: firebase dart flutter firebase-storage


【解决方案1】:

更新(2021-05-22):

FirebaseStorage.instance.refFromURL(url).delete() 现在应该使用。 之前建议的getReferenceFromUrl 似乎已从 API 中消失。

更新(2019-08-03):

根据this PR,FlutterFire 现在有一个getReferenceFromUrl method,允许通过其下载 URL 查找存储引用。


上一个答案:

在 Android 上,您可以调用 getReferenceForUrl() 从下载 URL 中获取 StorageReference,在 iOS 上也存在类似的方法。

但是我在FlutterFire reference docs中找不到对应的方法。不幸的是,这意味着在 Flutter 中无法从下载 URL 映射回 StorageReference

这听起来像是一个遗漏,所以我建议您在此 feature request 上 +1。

目前,这意味着您需要在 Cloud Storage 中拥有文件的相对路径才能将其从 Flutter 中删除。使用该路径,您当前的代码就可以工作。

【讨论】:

  • 嗯。好的,所以从我上面的代码 sn-p 中,我已经通过使用正则表达式删除不需要的字符来操纵下载 URL。这会在“filePath”变量中留下文件路径。然后我将它传递给函数的子参数。在上图中,“_pathComponents”列表变量不包含完整的下载 URL,但路径....应该是正确的...对吗?
  • 我不确定是否可以保证下载 URL 中嵌入的图像路径是 1:1。我总是将下载 URL 视为不透明的字符串。但是,如果您将图像的路径硬编码为default_images/user.png,这行得通吗?
  • 弗兰克你的传奇。 是的!那行得通。太感谢了。这一直困扰着我好几个星期!好的,操作该 url 字符串将非常困难,因此我可以动态删除文件。我想我们现在都必须这样做,直到实现“getReferenceForUrl()”功能。干杯
【解决方案2】:

将文件路径更改为

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' ));

【讨论】:

    【解决方案3】:

    我实现了一个更简洁的代码,但与@earyhe 相同,它使用Uri.decodeFull()Path.basename()。试过了,效果很好。

    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();
     }
    

    【讨论】:

      【解决方案4】:

      关于@Frank van Puffelen 的答案是代码 sn-p 参考 URL 从 Firebase 存储中删除文件

        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) {}
      }
      

      完整方法

      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();
      }
      

      【讨论】:

        【解决方案5】:
         if (post.imageURL != null) {
            StorageReference photoRef =
                await FirebaseStorage.instance.getReferenceFromUrl(post.imageURL);
        
            await photoRef.delete();
          }
        

        【讨论】:

        • 虽然这段代码可能会解决问题,但一个好的答案应该解释什么代码的作用以及如何它有帮助
        【解决方案6】:

        === 2020 年 12 月 ===

        非常感谢您的回答,这只是一个更新,因为旧方法导致我的应用程序崩溃。

        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();
        

        【讨论】:

        • 非常感谢,搜索了几个小时后得到了这个有效的答案!
        【解决方案7】:

        3. 3. 2021

        我不知道过去怎么样(因为我对 Flutter 和 Firebase 还很陌生),但目前它很简单。假设您要从 Firebase 存储中删除图像。为此,您将编写以下方法:

        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();
          }
        

        【讨论】:

          【解决方案8】:

          2021 年 8 月 10 日

          如果你想从 firebase 中删除图片,你必须拥有该图片的 url,就像 :

          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 然后,您只需将该 url 传递到:

           Reference photoRef =await FirebaseStorage.instance.refFromURL(imageUrl);
           await photoRef.delete().then((value) {
            print('deleted Successfully');
          });
          

          【讨论】:

            【解决方案9】:

            这个功能非常适合firebase存储链接

            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')); }
            

            【讨论】:

              【解决方案10】:

              你必须创建StorageReference storageReference; 的实例,然后像这样初始化它

              storageReference = await FirebaseStorage.instance
                                            .getReferenceFromUrl('photoUrl');
              

              您必须有 photoUrl 以便 storageReference 指向正确的图像。然后像这样删除它

              storageReference.delete();
              

              全部完成。

              【讨论】:

                【解决方案11】:

                随着最新的重大更改,这是我使用的以下简单方法。

                1. 将最新的firebase_storage 以及它需要的所有其他相关更新导入到您的pubspec.yaml。目前这是 firebase_storage 的以下内容:

                  dependencies:
                     firebase_storage: ^7.0.0
                  
                2. 如下导入包:

                  import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
                  
                3. 最后,在 try catch 中,您可以执行以下操作:

                  try 
                  {
                    await firebase_storage.FirebaseStorage.instance.ref('/images/something.jpg').delete();
                   } catch (e) {
                    debugPrint('Error deleting $yourReference: $e');
                  }
                  

                【讨论】:

                  猜你喜欢
                  • 2017-05-24
                  • 2019-10-29
                  • 2021-04-03
                  • 2019-06-03
                  • 2020-10-08
                  • 2021-11-13
                  • 2021-12-22
                  • 1970-01-01
                  • 2020-05-03
                  相关资源
                  最近更新 更多