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

Flutter中Cloud Firestore嵌套对象的创建、更新与数据读取方法

现有代码存在的问题

  • 缺少ArtistModal的序列化/反序列化方法,自定义类无法直接和Firestore存储的Map结构互转
  • TestModal的fromJson方法直接转换嵌套数组得到的是Map数组,不是ArtistModal类型,运行会报类型错误
  • TestModal的toMap方法直接传入ArtistModal数组,Firestore无法识别自定义类结构
  • 你编写的读写逻辑本身没有问题,修正Model层代码后即可正常运行

修正后的完整代码

1. ArtistModal补充序列化逻辑

class ArtistModal {
  final String artistName;
  final String artistImage;
  final String role;

  ArtistModal({
    required this.artistName,
    required this.artistImage,
    required this.role,
  });

  // 新增反序列化方法
  factory ArtistModal.fromJson(Map<String, dynamic> json) {
    return ArtistModal(
      artistName: json['artistName'] ?? '',
      artistImage: json['artistImage'] ?? '',
      role: json['role'] ?? '',
    );
  }

  // 新增序列化方法
  Map<String, dynamic> toMap() {
    return {
      'artistName': artistName,
      'artistImage': artistImage,
      'role': role,
    };
  }
}

2. 修正TestModal的序列化/反序列化逻辑

class TestModal {
  final String id;
  final String venueName;
  final String eventName;
  List<ArtistModal> artistModal = <ArtistModal>[];

  TestModal({
    required this.venueName,
    required this.id,
    required this.eventName,
    required this.artistModal,
  });

  factory TestModal.fromJson(Map<String, dynamic> json) {
    // 嵌套数组转换:把Firestore返回的Map数组逐个转成ArtistModal对象
    final artistRawList = json['artistModal'] as List? ?? [];
    final convertedArtistList = artistRawList.map((item) => ArtistModal.fromJson(item)).toList();
    return TestModal(
      venueName: json['venueName'] ?? '',
      eventName: json['eventName'] ?? '',
      artistModal: convertedArtistList,
      id: json['id'] ?? '',
    );
  }

  Map<String, dynamic> toMap() {
    // 嵌套数组转换:把ArtistModal对象数组逐个转成Map再存入Firestore
    final artistMapList = artistModal.map((item) => item.toMap()).toList();
    return {
      'venueName': venueName,
      'eventName': eventName,
      'artistModal': artistMapList,
      'id': id,
    };
  }
}

操作说明

  1. 你提供的fetchListOfTest、setTest方法无需修改,修正Model后即可正常实现数据的创建、合并更新、流式读取,注意提前正确初始化_testCollection:
final CollectionReference _testCollection = FirebaseFirestore.instance.collection('你的集合名称');
  1. UI侧读取展示嵌套列表的示例:
StreamBuilder<List<TestModal>>(
  stream: fetchListOfTest(),
  builder: (context, snapshot) {
    if (snapshot.hasError) return const Text('数据加载失败');
    if (!snapshot.hasData) return const CircularProgressIndicator();
    final testList = snapshot.data!;
    return ListView.builder(
      itemCount: testList.length,
      itemBuilder: (context, index) {
        final currentItem = testList[index];
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('活动名称:${currentItem.eventName}'),
            Text('场地:${currentItem.venueName}'),
            const Text('参演艺术家:'),
            // 嵌套渲染艺术家列表
            ...currentItem.artistModal.map((artist) => ListTile(
              leading: Image.network(artist.artistImage, width: 40, height: 40, fit: BoxFit.cover),
              title: Text(artist.artistName),
              subtitle: Text(artist.role),
            )),
            const Divider()
          ],
        );
      },
    );
  },
)
  1. 单独更新艺术家数组的简化操作:如果不需要修改其他字段,可以用Firestore数组操作方法避免传整个数组:
// 新增艺术家
_testCollection.doc('文档ID').update({
  'artistModal': FieldValue.arrayUnion([新增的ArtistModal对象.toMap()])
});
// 删除指定艺术家
_testCollection.doc('文档ID').update({
  'artistModal': FieldValue.arrayRemove([要删除的ArtistModal对象.toMap()])
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:36:03