如何使用颤振删除 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 存储文件?的主要内容,如果未能解决你的问题,请参考以下文章