如何使用颤振删除 Firebase 存储文件?

Posted

技术标签:

【中文标题】如何使用颤振删除 Firebase 存储文件?【英文标题】:How to delete a Firebase Storage file with flutter? 【发布时间】: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" 非常感谢提供临时解决方案,我被困了两个星期,如果不是你的解决方案,我只好等到期待已久的功能出现了。 【参考方案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】:

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

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

    dependencies:
       firebase_storage: ^7.0.0
    

    如下导入包:

    import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
    

    最后,在 try catch 中,您可以执行以下操作:

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

【讨论】:

以上是关于如何使用颤振删除 Firebase 存储文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Firebase 颤振应用程序中合并两个集合?

如何从 Firebase Firestore 获取数据并将其存储在列表中以在颤振小部件中使用?

使用颤振将图像上传并存储到firebase

如何使用颤振从firebase实时检索数据

如何从 URL 中删除 Firebase 存储文件

如何在 Flutter 中从 firebase 存储读取和写入文本文件?