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

Flutter Firebase工厂构造函数及Object转Map类型报错问题

问题修复方案

两个报错的根因和修复方式如下:

  • 第一个报错:_patientFromJson和_patientToJson被定义为类的实例方法,实例方法需要类实例化之后才能调用,但工厂构造函数运行时还没有生成类实例,自然访问不到。把两个方法改成类的静态方法即可,静态方法归属类本身,不需要实例就能调用。
  • 第二个报错:cloud_firestore 2.0及以上版本中,DocumentSnapshot.data()的返回值类型是Object?,不再默认返回Map<String, dynamic>,手动做一次类型强转即可匹配参数类型。

另外原有代码里还有两个隐藏问题:

  1. _patientFromJson传参顺序和构造函数定义的参数顺序不一致,会导致birth和genre字段数据错位
  2. Firestore存储的时间字段是Timestamp类型,直接赋值给DateTime类型的属性会触发类型错误,需要做一次类型转换。

修复后的完整可运行代码:

import 'package:cloud_firestore/cloud_firestore.dart';

class Patient {
  String? name;
  String? pass;
  String? image;
  String? genre;
  DateTime? birth;
  DocumentReference? reference;

  Patient(
    this.name,
    this.pass,
    this.genre,
    this.birth, {
    this.reference,
  });

  factory Patient.fromSnapshot(DocumentSnapshot snapshot) {
    // 强转data类型,解决第二个报错
    final snapshotData = snapshot.data()! as Map<String, dynamic>;
    Patient newPatient = Patient.fromJson(snapshotData);
    newPatient.reference = snapshot.reference;
    return newPatient;
  }

  factory Patient.fromJson(Map<String, dynamic> json) => _patientFromJson(json);

  Map<String, dynamic> toJson() => _patientToJson(this);

  @override
  String toString() => 'name $name';

  // 改为静态方法,解决第一个报错
  static Patient _patientFromJson(Map<String, dynamic> data) {
    return Patient(
      data['name'] as String?,
      data['pass'] as String?,
      data['genre'] as String?,
      // Firestore Timestamp 转 DateTime
      (data['birth'] as Timestamp?)?.toDate(),
    );
  }

  // 改为静态方法,解决第一个报错
  static Map<String, dynamic> _patientToJson(Patient instance) {
    return {
      'name': instance.name,
      'pass': instance.pass,
      'birth': instance.birth,
      'genre': instance.genre,
    };
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:27:33