无法通过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
相关产品推荐
相关产品推荐

