You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web图片上传Firebase Storage失败:[firebase_storage/object-not-found]目标引用不存在问题求助

解决Flutter Web上传Firebase Storage时的object-not-found错误

这个错误的核心原因很明确:你在文件还没完成上传到Firebase Storage的情况下,就尝试获取该文件的下载链接,同时路径里的特殊字符也可能帮倒忙。我帮你拆解问题并给出修复方案:

问题分析

  1. 异步操作未等待:你的uploadStorage函数中,调用put(file)是异步上传操作,但你没有等待它完成,就直接把路径赋值给_url,然后点击"Save Image"时就去请求该路径的下载链接——这时候Storage里根本还没有这个文件,自然报object-not-found。
  2. 路径含非法字符:DateTime.now().toString()生成的字符串包含冒号(比如2024-05-20 14:30:00.123),而Firebase Storage的路径不允许冒号这类特殊字符,这也会导致路径无效,找不到对象。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:39:06