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

Flutter从Firebase Storage加载图片失败,报ProgressEvent错误如何解决?

解决Flutter从Firebase Storage加载图片失败的问题

问题描述

使用Flutter开发应用时,尝试从Firebase Storage获取图片但无法显示,相关代码及报错信息如下:

代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

import '../widgets/action_bar.dart';

class HomeTab extends StatelessWidget {

  final CollectionReference  _productRef = FirebaseFirestore.instance.collection("products");

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Stack(
        children: [
          FutureBuilder<QuerySnapshot>(
            future: _productRef.get(),
            builder: (context , snapshot){
              if(snapshot.hasError){
                return Scaffold(
                  body: Center(
                    child: Text("Error ${snapshot.error}"),
                  ),
                );
              }


              if(snapshot.connectionState == ConnectionState.done){
                return ListView(
                  children: snapshot.data!.docs.map((document) {
                    return Container(
                      child: Image.network(
                        "${(document.data() as Map<String, dynamic>)["image"][0]}",
                      ),
                      //child: Text("name: ${(document.data() as Map<String, dynamic>)["name"]}"),
                    );
                  }).toList(),
                );
              }

                return Scaffold(
                  body: Center(
                    child: CircularProgressIndicator(),
                  ),
                );
             }

          ),

       ]
     ),
    );
  }
}

报错信息

══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
The following ProgressEvent$ object was thrown resolving an image codec:
  [object ProgressEvent]

When the exception was thrown, this was the stack

Image provider: NetworkImage("gs://second-ecommerce-b5666.appspot.com/IMG-20230520-WA0256.jpg",
  scale: 1)
Image key: NetworkImage("gs://second-ecommerce-b5666.appspot.com/IMG-20230520-WA0256.jpg", scale: 1)
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: [object ProgressEvent]
Another exception was thrown: [object ProgressEvent]

问题原因

Image.network仅支持加载HTTP/HTTPS协议的公开网络链接,而代码中使用的gs://开头的路径是Firebase Storage的内部存储桶路径,并非可直接访问的网络地址,因此无法被解析加载。

解决方法

方法1:直接替换为公开HTTP下载链接

  1. 打开Firebase控制台,进入Storage页面找到目标图片文件
  2. 点击文件右侧的更多选项,选择「获取下载链接」
  3. 将生成的HTTPS链接替换到Firestore文档中image字段的对应值,之后Image.network即可正常加载图片

方法2:通过Firebase Storage SDK动态获取下载URL

  1. 先在pubspec.yaml中添加firebase_storage依赖:
dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^latest_version
  firebase_storage: ^latest_version
  1. 修改代码,通过SDK获取可访问的下载URL:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';

import '../widgets/action_bar.dart';

class HomeTab extends StatelessWidget {

  final CollectionReference _productRef = FirebaseFirestore.instance.collection("products");
  final FirebaseStorage _storage = FirebaseStorage.instance;

  // 获取文件下载URL的方法
  Future<String> getDownloadUrl(String filePath) async {
    final ref = _storage.ref().child(filePath);
    return await ref.getDownloadURL();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Stack(
        children: [
          FutureBuilder<QuerySnapshot>(
            future: _productRef.get(),
            builder: (context, snapshot) {
              if (snapshot.hasError) {
                return Scaffold(
                  body: Center(
                    child: Text("Error ${snapshot.error}"),
                  ),
                );
              }

              if (snapshot.connectionState == ConnectionState.done) {
                return ListView(
                  children: snapshot.data!.docs.map((document) {
                    // 提取存储桶后的文件路径
                    String imagePath = (document.data() as Map<String, dynamic>)["image"][0]
                        .replaceFirst("gs://second-ecommerce-b5666.appspot.com/", "");
                    // 嵌套FutureBuilder获取下载URL
                    return FutureBuilder<String>(
                      future: getDownloadUrl(imagePath),
                      builder: (context, urlSnapshot) {
                        if (urlSnapshot.connectionState == ConnectionState.done && urlSnapshot.hasData) {
                          return Container(
                            child: Image.network(urlSnapshot.data!),
                          );
                        }
                        // URL加载中显示指示器
                        return Container(
                          height: 100,
                          child: Center(child: CircularProgressIndicator()),
                        );
                      },
                    );
                  }).toList(),
                );
              }

              return Scaffold(
                body: Center(
                  child: CircularProgressIndicator(),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

注意事项

  • 使用方法2时,需确保Firebase Storage的安全规则允许当前用户读取文件。开发环境可临时使用宽松规则测试:
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}
  • 正式环境必须设置严格的权限规则,防止数据泄露。

内容的提问来源于stack exchange,提问作者amal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:30:37