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, }; } }
操作说明
- 你提供的
fetchListOfTest、setTest方法无需修改,修正Model后即可正常实现数据的创建、合并更新、流式读取,注意提前正确初始化_testCollection:
final CollectionReference _testCollection = FirebaseFirestore.instance.collection('你的集合名称');
- 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() ], ); }, ); }, )
- 单独更新艺术家数组的简化操作:如果不需要修改其他字段,可以用Firestore数组操作方法避免传整个数组:
// 新增艺术家 _testCollection.doc('文档ID').update({ 'artistModal': FieldValue.arrayUnion([新增的ArtistModal对象.toMap()]) }); // 删除指定艺术家 _testCollection.doc('文档ID').update({ 'artistModal': FieldValue.arrayRemove([要删除的ArtistModal对象.toMap()]) });
内容的提问来源于stack exchange,提问作者Kaushal Kishore
相关产品推荐
相关产品推荐

