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

Flutter加载Firebase Storage图片报404对象不存在错误如何解决

Flutter 加载Firebase Storage图片返回404 object-not-found 故障修复

报错日志

E/StorageException( 1371): StorageException has occurred.
E/StorageException( 1371): Object does not exist at location.
E/StorageException( 1371):  Code: -13010 HttpResult: 404
E/StorageException( 1371): {  "error": {    "code": 404,    "message": "Not Found."  }}
E/StorageException( 1371): java.io.IOException: {  "error": {    "code": 404,    "message": "Not Found."  }}
E/StorageException( 1371):  at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
E/StorageException( 1371):  at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
E/StorageException( 1371):  at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
E/StorageException( 1371):  at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
E/StorageException( 1371):  at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
E/StorageException( 1371):  at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
E/StorageException( 1371):  at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
E/StorageException( 1371):  at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
E/StorageException( 1371):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/StorageException( 1371):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/StorageException( 1371):  at java.lang.Thread.run(Thread.java:923)
I/flutter ( 1371): [firebase_storage/object-not-found] No object exists at the desired reference.

原有实现代码

UI构建部分:

FutureBuilder(
          future: getUserImagePath(),
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            if (snapshot.connectionState == ConnectionState.done &&
                snapshot.hasData) {
              return Image.network(
                snapshot.data!,
                fit: BoxFit.cover,
              );
            }
            if (snapshot.hasError) {
              print(snapshot.error);
            }
            return Container();
          })

路径获取方法:

Future<String> getUserImagePath() async {
    final user = await FirebaseAuth.instance.currentUser;
    String userEmail = user!.email.toString();
    print(userEmail);
    final userRef = await FirebaseStorage.instance.ref();
    String urlPath = 'users/${userEmail}/userProfile.jpeg';
    final userProfileUrl = await userRef.child(urlPath).getDownloadURL();
    print(userProfileUrl);

    return userProfileUrl;
  }

存储结构参考

Firebase Storage文件存储结构截图

问题排查方向

  • 核对实际请求路径和存储路径一致性:先打印运行时生成的urlPath变量值,和控制台显示的文件完整路径逐字符匹配,重点检查文件名后缀大小写(比如实际是.jpg/.JPEG而非.jpeg)、文件夹层级是否正确。
  • 检查特殊字符转义问题:邮箱包含@、.等特殊字符,如果上传文件时对邮箱做了URL编码(@会被转成%40),代码里直接用原始邮箱字符串拼路径就会找不到对象。
  • 确认存储桶引用正确:如果项目使用了非默认Firebase Storage存储桶,直接调用FirebaseStorage.instance.ref()会指向默认桶,和文件实际存储的桶不匹配也会返回404。
  • 排除权限规则干扰:部分场景下Storage权限规则配置错误,会把无权限访问的请求返回为404而非403,可以临时配置公开访问规则测试是否为权限问题。

修复代码

修正后的路径获取方法,增加空值兜底、字符转义、调试日志:

Future<String> getUserImagePath() async {
  final user = FirebaseAuth.instance.currentUser;
  final String? userEmail = user?.email;
  if (userEmail == null) {
    throw Exception('当前用户未登录,无法获取头像');
  }
  // 对邮箱做URL编码,和上传时的路径规则保持一致
  final String encodedEmail = Uri.encodeComponent(userEmail);
  // 如果使用非默认存储桶,替换为instanceFor指定桶地址
  // final storageRef = FirebaseStorage.instanceFor(bucket: '你的存储桶地址').ref();
  final storageRef = FirebaseStorage.instance.ref();
  // 注意文件名后缀和控制台完全一致,不要写错大小写
  final String filePath = 'users/$encodedEmail/userProfile.jpeg';
  debugPrint('实际请求的Storage路径: $filePath');
  final String downloadUrl = await storageRef.child(filePath).getDownloadURL();
  return downloadUrl;
}

修正后的FutureBuilder,增加加载态、错误态兜底,方便排查问题:

FutureBuilder(
  future: getUserImagePath(),
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    // 加载中状态
    if (snapshot.connectionState != ConnectionState.done) {
      return const SizedBox(
        width: 48,
        height: 48,
        child: CircularProgressIndicator(strokeWidth: 2),
      );
    }
    // 加载错误状态
    if (snapshot.hasError) {
      debugPrint('加载用户头像失败: ${snapshot.error}');
      return const Icon(Icons.person, size: 48);
    }
    // 加载成功
    if (snapshot.hasData) {
      return Image.network(
        snapshot.data!,
        fit: BoxFit.cover,
        // 图片加载失败兜底
        errorBuilder: (context, error, stackTrace) {
          debugPrint('图片渲染失败: $error');
          return const Icon(Icons.broken_image, size: 48);
        },
      );
    }
    return const SizedBox.shrink();
  }
)

如果调整路径后还是报错,可以直接在Firebase控制台打开目标文件详情,手动复制文件的完整引用路径,替换到代码里做对照测试,确认文件本身可正常访问。


内容的提问来源于stack exchange,提问作者S I D D H A R D H A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 02:57:25