Flutter Web图片上传Firebase Storage失败:[firebase_storage/object-not-found]目标引用不存在问题求助
解决Flutter Web上传Firebase Storage时的
object-not-found错误 这个错误的核心原因很明确:你在文件还没完成上传到Firebase Storage的情况下,就尝试获取该文件的下载链接,同时路径里的特殊字符也可能帮倒忙。我帮你拆解问题并给出修复方案:
问题分析
- 异步操作未等待:你的
uploadStorage函数中,调用put(file)是异步上传操作,但你没有等待它完成,就直接把路径赋值给_url,然后点击"Save Image"时就去请求该路径的下载链接——这时候Storage里根本还没有这个文件,自然报object-not-found。 - 路径含非法字符:
DateTime.now().toString()生成的字符串包含冒号(比如2024-05-20 14:30:00.123),而Firebase Storage的路径不允许冒号这类特殊字符,这也会导致路径无效,找不到对象。 - Storage实例混用:你同时用了
fb.storage()(JS端的Firebase)和storage.ref()(Dart端的Firebase Storage插件),实例不一致可能导致路径解析错误。
修复代码
1. 统一使用Dart的Firebase Storage插件,等待上传完成后获取下载链接
修改uploadStorage为异步函数,等待上传完成并返回下载链接:
import 'package:firebase_storage/firebase_storage.dart'; Future<String?> uploadStorage() async { final dateTime = DateTime.now(); // 用时间戳替代含特殊字符的时间字符串,避免路径非法 final path = 'bannerImage/${dateTime.millisecondsSinceEpoch}'; final completer = Completer<String?>(); uploadImage(onSelected: (file) async { if (file == null) { completer.complete(null); return; } setState(() { _fileNameTextController.text = file.name; _imageSelected = false; }); // 使用Dart官方的Firebase Storage实例 final storageRef = FirebaseStorage.instance.ref().child(path); final uploadTask = storageRef.putFile(file); try { // 等待上传完成 await uploadTask.whenComplete(() async {}); // 获取下载链接 final downloadUrl = await storageRef.getDownloadURL(); completer.complete(downloadUrl); } catch (e) { print('上传失败:$e'); completer.complete(null); } }); return completer.future; }
2. 修改Save Image按钮的逻辑,直接使用上传完成后的链接
不需要再调用uploadBannerImageToDb去重复获取链接,直接存储已拿到的下载链接:
AbsorbPointer( absorbing: _imageSelected, child: FlatButton( onPressed: () async { progressDialog.show(); try { final downloadUrl = await uploadStorage(); if (downloadUrl != null) { // 直接将下载链接存入Firestore await FirebaseFirestore.instance.collection('slider').add({ 'image': downloadUrl, }); progressDialog.dismiss(); _services.showMyDialog( title: 'New Banner Image', message: 'Saved Banner Image Succesfully', context: context, ); } else { progressDialog.dismiss(); // 提示用户未选择有效文件或上传失败 } } catch (e) { progressDialog.dismiss(); print('存储失败:$e'); // 展示错误提示给用户 } }, child: Text('Save Image', style: TextStyle(color: Colors.white)), color: _imageSelected ? Colors.grey : Colors.black45, ), )
3. 移除冗余的uploadBannerImageToDb函数
现在我们已经在上传完成后直接获取了下载链接,这个函数可以删掉,避免重复操作。
额外注意事项
- 始终确保Firebase服务的初始化正确,并且当前用户有足够的Storage上传权限(检查Firebase控制台的Storage安全规则)。
- 可以给上传过程添加进度监听,比如用
uploadTask.snapshotEvents来实时更新上传进度,提升用户体验。 - 处理上传和存储过程中的异常,给用户清晰的错误提示,而不是只在控制台打印。
内容的提问来源于stack exchange,提问作者mustafa
相关产品推荐
相关产品推荐

