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

无法通过Firestore中的Firebase Storage链接在PDF报告中显示图片

问题描述

已将图片上传至Firebase Storage,图片链接存储在Firestore中,需要在PDF报告中展示图片。实现逻辑为:获取图片链接→下载图片并转换为字节数据→在PDF中展示。但调用http.get请求图片链接时抛出ClientException: XMLHttpRequest error,已确认执行下载操作的用户完成认证,Firebase Storage规则要求request.auth != null才能读写。


下载图片的代码

var response;
var imageData;
try {
  response = await http.get(Uri.parse(imageUrl!));
  if (response.statusCode == 200) { // Check for successful response
    imageData = response.bodyBytes;
  } else {
    print('Error fetching image: ${response.statusCode}');
  }
} catch (e) {
  print('Error: $e');
}

PDF展示图片的代码

pw.Align(
  alignment: pw.Alignment.bottomLeft,
  child: pw.Image(
    pw.MemoryImage(imageData),
    width: 100,
    height: 80,
  ),
),

错误信息

Error: ClientException: XMLHttpRequest error., uri=https://firebasestorage.googleapis.com/v0/b/dmlive-1128c.appspot.com/o/1704722630561?alt=media&token=4b4de6d3-0c4e-411f-9f2c-28d7c30cdde2

Firebase Storage规则

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

解决方案

原因分析

直接用http.get请求Firebase Storage文件链接时,请求头未携带用户认证信息,导致Storage规则校验不通过,返回权限错误,表现为XMLHttpRequest异常。

解决办法

方法1:使用Firebase Storage SDK获取文件字节(推荐)

改用Firebase Storage SDK下载文件,SDK会自动携带当前认证用户的令牌,符合规则要求:

import 'package:firebase_storage/firebase_storage.dart';

// 方式1:通过文件路径获取(Firestore中存储的Storage文件路径,如"1704722630561")
final storageRef = FirebaseStorage.instance.ref().child("1704722630561");
try {
  imageData = await storageRef.getData();
} catch (e) {
  print('Error downloading image: $e');
}

// 方式2:通过完整下载链接获取
final storageRef = FirebaseStorage.instance.refFromURL(imageUrl!);
imageData = await storageRef.getData();

方法2:给http请求手动添加认证令牌

如果坚持使用http.get,需手动获取当前用户的ID Token并添加到请求头:

import 'package:firebase_auth/firebase_auth.dart';

var response;
var imageData;
try {
  final idToken = await FirebaseAuth.instance.currentUser?.getIdToken();
  final headers = {
    'Authorization': 'Bearer $idToken',
  };
  response = await http.get(Uri.parse(imageUrl!), headers: headers);
  if (response.statusCode == 200) {
    imageData = response.bodyBytes;
  } else {
    print('Error fetching image: ${response.statusCode}');
  }
} catch (e) {
  print('Error: $e');
}

注意事项

  • 下载前确认FirebaseAuth.instance.currentUser不为null,确保用户处于已认证状态
  • 避免临时放宽Storage规则(如允许公开读),防止引发安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:33:29