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

Flutter向Firestore上传Offset数据报错的解决方法

Flutter 上传 Offset 类型数据到 Firestore 报错解决

问题现象

  • 基于 CustomPaint 实现简易绘图功能,线条坐标以 Flutter 内置 Offset 类型存储,直接将 Offset 实例传入 Firestore 上传接口时触发报错:
Invalid argument: Instance of 'Offset'
  • 目标上传数据结构参考:
{
  "nickname": "dgh",
  "point": [
    "Offset(110.0, 265.4)",
    "Offset(110.5, 265.6)",
    "Offset(110.9, 266.1)",
    "Offset(111.3, 266.7)"
  ],
  "color": "MaterialColor(primary value: Color(0xffff5722))",
  "width": 5.0
}
  • 触发报错的测试代码:
await FirebaseFirestore.instance
    .collection(COL_ROOMS)
    .doc(widget.roomKey)
    .collection(COL_DRAW) 
    .doc()
    .set({
      "name": "test",
      "offset": Offset(1, 1), // 该行触发类型错误
    })
    .then((value) => logger.d("upload!"))
    .catchError((error) => logger.w(error));

报错原因

Firestore 仅支持字符串、数字、布尔、数组、键值对Map、时间戳这类原生可序列化数据类型,无法直接识别 Flutter 框架自定义的 Offset、MaterialColor 等对象实例,直接传入就会抛出参数非法错误。

解决方法

根据后续数据读取的需求,二选一即可:

方案1:按字符串格式存储

如果需要和参考结构一致存为字符串格式,直接调用对象自带的 toString() 方法转换即可,颜色类型也可按同样逻辑处理:

.set({
  "name": "test",
  "nickname": "dgh",
  "width": 5.0,
  // 单个Offset转字符串
  "offset": const Offset(1, 1).toString(),
  // Offset列表批量转字符串
  "point": points.map((e) => e.toString()).toList(),
  // 颜色转字符串
  "color": brushColor.toString(),
})

后续读取数据时,自行解析字符串中的x、y坐标值,即可还原为Offset实例。

方案2:结构化存储(推荐)

将Offset拆分为包含dx、dy两个浮点值的Map存储,无需额外字符串解析,读取还原更方便,也支持Firestore侧的数值查询:

// 单Offset转可序列化Map
Map<String, double> _offsetToMap(Offset offset) => {
  "dx": offset.dx,
  "dy": offset.dy
};

// Offset列表批量转换
List<Map<String, double>> _offsetListToMap(List<Offset> offsets) {
  return offsets.map(_offsetToMap).toList();
}

// 上传时调用
.set({
  "name": "test",
  "nickname": "dgh",
  "width": 5.0,
  "offset": _offsetToMap(const Offset(1,1)),
  "point": _offsetListToMap(points),
  // 颜色存32位int值,还原比字符串更方便
  "color": brushColor.value,
})

读取数据时,直接取Map中的dx、dy值即可还原Offset:

Offset _offsetFromMap(Map<String, dynamic> data) {
  return Offset(data["dx"] as double, data["dy"] as double);
}

如果存了颜色的int值,读取时直接调用 Color(colorIntValue) 即可还原为Color实例,无需解析字符串。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:57:21