如何在Flutter Quill中将本地图片替换为Firebase存储URL
解决方案
实现逻辑
- 从Quill文档的Delta结构中提取所有本地图片路径
- 批量上传图片到Firebase Storage并获取在线访问URL
- 替换Delta中的本地路径为Storage返回的在线URL
- 导出更新后的JSON格式文档
完整代码实现
import 'dart:convert'; import 'package:flutter_quill/flutter_quill.dart'; // 如需生成唯一文件名,添加uuid依赖:uuid: ^4.3.3 import 'package:uuid/uuid.dart'; // 保留你原有的函数 Future<String> onUpload() async{ return jsonEncode(controller.document.toDelta().toJson()); } Future<String?> uploadAssetsToStore({required String filePath, required String folderName, required String fileName}) async{ return await StorageService().uploadFile(filePath, folderName, fileName); } // 核心处理函数 Future<String> uploadDocumentWithImages() async { // 1. 获取原始Delta数据 final delta = controller.document.toDelta(); final List<Map<String, dynamic>> ops = List.from(delta.toJson()['ops']); // 2. 提取所有本地图片路径并去重 final Set<String> localImagePaths = {}; for (final op in ops) { if (op['insert'] is Map) { final insertMap = op['insert'] as Map; if (insertMap.containsKey('image')) { final imagePath = insertMap['image'] as String; // 根据实际场景调整本地路径判断逻辑 if (imagePath.startsWith('file://') || !imagePath.startsWith('http')) { localImagePaths.add(imagePath.replaceFirst('file://', '')); } } } } // 3. 批量上传图片,建立本地路径与在线URL的映射 final Map<String, String> pathToUrlMap = {}; final uuid = Uuid(); for (final path in localImagePaths) { // 生成唯一文件名避免重复覆盖 final fileName = '${uuid.v4()}.${path.split('.').last}'; final url = await uploadAssetsToStore( filePath: path, folderName: 'quill_doc_images', // 自定义存储文件夹名 fileName: fileName ); if (url != null) { pathToUrlMap[path] = url; } } // 4. 替换Delta中的本地路径为在线URL final List<Map<String, dynamic>> updatedOps = []; for (final op in ops) { if (op['insert'] is Map) { final insertMap = Map.from(op['insert'] as Map); if (insertMap.containsKey('image')) { final imagePath = insertMap['image'] as String; final localPath = imagePath.replaceFirst('file://', ''); if (pathToUrlMap.containsKey(localPath)) { insertMap['image'] = pathToUrlMap[localPath]; } } updatedOps.add({'insert': insertMap, ...op}); } else { updatedOps.add(op); } } // 5. 生成更新后的JSON文档 final updatedDeltaJson = {'ops': updatedOps}; return jsonEncode(updatedDeltaJson); }
使用说明
- 调用
uploadDocumentWithImages()替代原有的onUpload(),即可完成图片上传+文档导出的完整流程 - 可根据需求修改
folderName为Firebase Storage中对应的存储文件夹名称 - 若不需要uuid生成唯一文件名,可替换为自定义命名规则(比如文档ID+时间戳)
- 本地路径的判断逻辑需根据你实际的图片插入方式调整(部分场景下路径可能不带
file://前缀)
内容的提问来源于stack exchange,提问作者Savin Kisunu
相关产品推荐
相关产品推荐

