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; }
存储结构参考

问题排查方向
- 核对实际请求路径和存储路径一致性:先打印运行时生成的
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
相关产品推荐
相关产品推荐

