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

Flutter中无法将年龄数据插入Firestore问题求助

DateDuration类型数据写入Firestore失败的解决方法

问题描述

通过日期选择器获取生日日期后,使用AgeCalculator计算出DateDuration类型的年龄,能正常显示在界面上,但点击提交按钮将数据插入Firestore时出现报错。

原代码片段

DateDuration? duration;

void calAge() {
  DateTime? birthday = selectedDate;

  duration = AgeCalculator.age(birthday!);
  print('Your age is $duration');
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      margin: EdgeInsets.all(40),
      width: double.infinity,
      height: MediaQuery.of(context).size.height * 0.25,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          ElevatedButton(
            child: Text("Show DatePicker"),
            onPressed: () {
              showDatePicker();
            },
          ),
          Text(selectedDate == null ? "" : "$selectedDate"),
          Text(selectedDate == null ? "" : "$duration"),
          ElevatedButton(
            onPressed: () {
              send();
            },
            child: const Text("submit"),
          ),
        ],
      ),
    ),
  );
}

void send() {
  FirebaseFirestore.instance.collection("data").doc().set({
    "field5": selectedDate,
    "field6": duration,
  });
}

报错原因

Firestore仅支持存储特定的原生数据类型(如String、int、double、bool、DateTime、Map、List等),而DateDuration是第三方库定义的自定义类,Firestore无法自动序列化该对象,因此直接写入会触发错误。

解决方案

将DateDuration转换为Firestore支持的格式再进行存储,常用两种方式:

方式1:拆分为年/月/日的Map存储

把DateDuration中的年、月、日属性提取出来,封装成Map对象,Firestore可以直接存储这种结构:

void send() {
  // 将DateDuration转为Map
  Map<String, dynamic>? ageMap;
  if (duration != null) {
    ageMap = {
      'years': duration!.years,
      'months': duration!.months,
      'days': duration!.days,
    };
  }

  FirebaseFirestore.instance.collection("data").doc().set({
    "field5": selectedDate,
    "field6": ageMap,
  });
}

读取时还原:如果需要在后续读取数据时恢复为DateDuration对象,可以这样处理:

// 读取示例
DocumentSnapshot doc = await FirebaseFirestore.instance.collection("data").doc("目标文档ID").get();
Map<String, dynamic>? ageMap = doc['field6'];
if (ageMap != null) {
  DateDuration restoredDuration = DateDuration(
    years: ageMap['years'],
    months: ageMap['months'],
    days: ageMap['days'],
  );
}

方式2:转为字符串存储

如果只需要展示年龄,不需要后续计算,可以直接把DateDuration转为字符串存储:

void send() {
  String? ageString;
  if (duration != null) {
    ageString = '${duration!.years}岁${duration!.months}个月${duration!.days}天';
  }

  FirebaseFirestore.instance.collection("data").doc().set({
    "field5": selectedDate,
    "field6": ageString,
  });
}

内容的提问来源于stack exchange,提问作者Dasun Dola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:40:39