Flutter向Firebase上传带扩展名文件及URL优化技术咨询
问题:Flutter上传文件到Firebase Storage时,如何让生成的下载URL包含文件扩展名?
正常上传图片或文件后,得到的URL格式如下:
https://firebasestorage.googleapis.com/v0/b/petpulz-93d6f.appspot.com/o/records%2Fpost_1683391240123?alt=media&token=3fa03aa4-78f4-4329-bacf-5793072055e1
这类URL在获取、重新打开或下载文件时,无法被识别文件类型。请问有没有办法在上传时让生成的URL末尾添加对应的扩展名(比如.pdf、.jpg、.doc)?
以下是当前上传文件到Firebase Storage并将下载URL存入Firestore的代码:
Future<void> _uploadFiles() async { final postID = DateTime.now().millisecondsSinceEpoch.toString(); final storage = FirebaseStorage.instance; final firestore = FirebaseFirestore.instance; final List<String> downloadUrls = []; for (final file in _selectedFiles) { final ref = storage.ref().child("user").child("post_$postID"); final uploadTask = ref.putFile(file); final snapshot = await uploadTask.whenComplete(() {}); final downloadUrl = await snapshot.ref.getDownloadURL(); downloadUrls.add(downloadUrl); } await firestore.collection("users") .doc(user?.uid) .set({ "username" : title.text, 'fileUrls': FieldValue.arrayUnion(downloadUrls), }); Navigator.of(context).push(MaterialPageRoute(builder: (context) => HomeScreen())); }
解决方案
核心问题在于创建Storage引用时未给文件名添加原始文件的扩展名,只需在构建存储路径时拼接原文件扩展名即可。
步骤1:获取原文件的扩展名
可以借助path包的extension方法提取扩展名(需先在pubspec.yaml中添加path: ^1.8.3依赖):
import 'package:path/path.dart' as path; // 在循环内获取当前文件的扩展名 final fileExtension = path.extension(file.path);
步骤2:创建带扩展名的Storage引用
修改存储引用的创建逻辑,把扩展名拼到文件名后:
final ref = storage.ref().child("user").child("post_$postID$fileExtension");
修改后的完整代码
import 'package:path/path.dart' as path; Future<void> _uploadFiles() async { final postID = DateTime.now().millisecondsSinceEpoch.toString(); final storage = FirebaseStorage.instance; final firestore = FirebaseFirestore.instance; final List<String> downloadUrls = []; for (final file in _selectedFiles) { // 获取文件扩展名 final fileExtension = path.extension(file.path); // 创建带扩展名的存储引用 final ref = storage.ref().child("user").child("post_$postID$fileExtension"); final uploadTask = ref.putFile(file); final snapshot = await uploadTask.whenComplete(() {}); final downloadUrl = await snapshot.ref.getDownloadURL(); downloadUrls.add(downloadUrl); } await firestore.collection("users") .doc(user?.uid) .set({ "username" : title.text, 'fileUrls': FieldValue.arrayUnion(downloadUrls), }); Navigator.of(context).push(MaterialPageRoute(builder: (context) => HomeScreen())); }
额外说明
- 上传后生成的下载URL会包含扩展名,例如
https://xxx.appspot.com/o/user%2Fpost_1683391240123.jpg?alt=media&token=xxx,系统可据此正确识别文件类型。 - 若一次上传多个文件,为避免重名,可给每个文件单独生成唯一标识+扩展名:
final fileName = "${DateTime.now().millisecondsSinceEpoch}$fileExtension"; final ref = storage.ref().child("user").child(fileName);
内容的提问来源于stack exchange,提问作者Dasun Dola
相关产品推荐
相关产品推荐

