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

如何在Flutter Quill中将本地图片替换为Firebase存储URL

解决方案

实现逻辑

  1. 从Quill文档的Delta结构中提取所有本地图片路径
  2. 批量上传图片到Firebase Storage并获取在线访问URL
  3. 替换Delta中的本地路径为Storage返回的在线URL
  4. 导出更新后的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:30:57