如何将Flutter中qr_flutter生成的QR二维码保存至Firebase
实现步骤
- 给QrImage组件包裹
RepaintBoundary并绑定全局渲染Key,用于捕获组件的渲染内容 - 编写组件转PNG字节流的方法
- 将字节流上传到Firebase Storage,获取公网访问地址后存入Firestore对应文档
代码修改示例
首先补充导入依赖:
import 'dart:typed_data'; import 'package:firebase_storage/firebase_storage.dart';
在State类中新增全局Key和Storage实例:
class _HomeScreenState extends State<GeneraQR> { // 原有代码不变 final GlobalKey _qrKey = GlobalKey(); final FirebaseStorage _storage = FirebaseStorage.instance; // 原有代码不变 }
修改QrImage外层结构,绑定渲染Key:
Center( child: RepaintBoundary( key: _qrKey, child: QrImage( data: qrData+qrData2+qrData3+qrData4, version: QrVersions.auto, size: 165.0, backgroundColor: Colors.white, errorStateBuilder: (cxt, err) { return Container( child: Center( child: Text( "Something gone wrong ...", textAlign: TextAlign.center, ), ), ); }, ), ), )
新增二维码转字节流方法:
Future<Uint8List?> _captureQrImage() async { try { RenderRepaintBoundary boundary = _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary; // pixelRatio数值越大生成的图片越清晰,文件体积也对应更大 var image = await boundary.toImage(pixelRatio: 3.0); ByteData? byteData = await image.toByteData(format: ImageByteFormat.png); return byteData?.buffer.asUint8List(); } catch (e) { print("二维码捕获失败:$e"); return null; } }
修改按钮提交逻辑,新增图片上传和字段存储:
onPressed: () async { if(qrdataFeed.text.isEmpty||qrdataFeed2.text.isEmpty||qrdataFeed3.text.isEmpty||qrdataFeed4.text.isEmpty){ _onAlertButtonPressedError(context); }else{ _onAlertButtonPressedConfirm(context); setState(() { qrData = qrdataFeed.text; qrData2 = qrdataFeed2.text; qrData3 = qrdataFeed3.text; qrData4 = qrdataFeed4.text; }); // 等待200毫秒确保二维码渲染完成 await Future.delayed(const Duration(milliseconds: 200)); Uint8List? qrBytes = await _captureQrImage(); // 写入基础字段拿到文档引用 DocumentReference docRef = await articolo.add({ 'nome': qrdataFeed.text, 'descrizione': qrdataFeed2.text, 'pezzi': qrdataFeed3.text, 'prezzo': qrdataFeed4.text, }); // 上传二维码到Storage并更新文档 if(qrBytes != null) { Reference storageRef = _storage.ref().child('qr_codes/${docRef.id}.png'); await storageRef.putData(qrBytes); String downloadUrl = await storageRef.getDownloadURL(); await docRef.update({'qrImageUrl': downloadUrl}); } } },
注意事项
- 需提前配置Firebase Storage的读写权限,测试阶段可临时使用宽松规则,上线前需调整为符合业务安全要求的规则
- 如果不需要长期保存二维码图片,也可以直接把生成的字节流转成Base64字符串存入Firestore,缺点是会占用更多文档存储空间
内容的提问来源于stack exchange,提问作者Turf
相关产品推荐
相关产品推荐

