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

Flutter加载Firebase Storage图片失败,URL可正常访问

Flutter Firebase Storage图片加载失败(ProgressEvent异常)

尝试从Firebase Storage获取图片,已成功获取到下载URL,且URL在浏览器中能正常打开对应图片,但Flutter的Image.network组件始终无法加载图片,抛出ProgressEvent相关异常。

代码示例

import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('I try so hard and got no far:<'),
        ),
        body: ImageList(),
      ),
    );
  }
}

class ImageList extends StatefulWidget {
  @override
  _ImageListState createState() => _ImageListState();
}

class _ImageListState extends State<ImageList> {
  List<String> imageUrls = [];

  @override
  void initState() {
    super.initState();
    loadImages();
  }

  Future<void> loadImages() async {
    String directoryPath = 'Images/';
    Reference reference = FirebaseStorage.instance.ref().child(directoryPath);
    ListResult result = await reference.listAll();

    List<String> urls = [];
    for (Reference ref in result.items) {
      String url = await ref.getDownloadURL();
      urls.add(url);
    }

    setState(() {
      imageUrls = urls;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: imageUrls.length,
      itemBuilder: (context, index) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Image.network(
            imageUrls[index],
            width: 200.0,
            height: 200.0,
            fit: BoxFit.cover,
          ),
        );
      },
    );
  }
}

错误信息

The following ProgressEvent$ object was thrown resolving an image codec:
[object ProgressEvent]

When the exception was thrown, this was the stack:
Image provider: NetworkImage("https://firebasestorage.googleapis.com/v0/b/carousel-a996b.appspot.com/o/Images%2F1.png?alt=media&token=017d99a3-b909-4c2f-b2fe-e7ae1f282327", scale: 1.0)
Image key: NetworkImage("https://firebasestorage.googleapis.com/v0/b/carousel-a996b.appspot.com/o/Images%2F1.png?alt=media&token=017d99a3-b909-4c2f-b2fe-e7ae1f282327", scale: 1.0)


解决方案

1. 检查平台网络权限

  • Android:确保android/app/src/main/AndroidManifest.xml中添加了网络权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • iOS:在ios/Runner/Info.plist中确认App Transport Security设置允许HTTPS请求,若有严格限制需添加Firebase Storage域名例外:
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>firebasestorage.googleapis.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <false/>
            </dict>
        </dict>
    </dict>
    

2. 优化异步加载逻辑,添加状态处理

用FutureBuilder替代initState中手动调用异步方法,确保数据加载完成后再构建UI,避免空数据或未就绪状态:

class ImageList extends StatelessWidget {
  Future<List<String>> loadImages() async {
    String directoryPath = 'Images/';
    Reference reference = FirebaseStorage.instance.ref().child(directoryPath);
    ListResult result = await reference.listAll();

    List<String> urls = [];
    for (Reference ref in result.items) {
      String url = await ref.getDownloadURL();
      urls.add(url);
    }
    return urls;
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<String>>(
      future: loadImages(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        }
        if (snapshot.hasError) {
          return Center(child: Text('加载失败: ${snapshot.error}'));
        }
        final imageUrls = snapshot.data ?? [];
        return ListView.builder(
          itemCount: imageUrls.length,
          itemBuilder: (context, index) {
            return Padding(
              padding: const EdgeInsets.all(8.0),
              child: Image.network(
                imageUrls[index],
                width: 200.0,
                height: 200.0,
                fit: BoxFit.cover,
                errorBuilder: (context, error, stackTrace) {
                  print('图片加载错误详情: $error');
                  return Icon(Icons.broken_image, size: 100);
                },
              ),
            );
          },
        );
      },
    );
  }
}

3. 添加错误捕获,排查具体问题

在Image.network中加入errorBuilder,打印详细错误信息,帮助定位问题根源(比如证书问题、网络波动等)。

4. 验证Firebase Storage安全规则

确认Storage的读取权限配置正确,开发阶段可临时设置宽松规则测试:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }
  }
}

上线前需调整为符合业务需求的权限规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 00:53:29