Flutter中如何将Firestore集合及嵌套文档转为PODO并读取数据
在Flutter中将Firestore嵌套数据转换为PODO的方法
当然可以实现,不管是简单结构还是嵌套层级的数据,都能转换成PODO(Plain Old Dart Object)来读取,下面是两种常用的实现方式:
方法一:手动实现转换逻辑
适合结构简单的场景,直接在PODO类中编写从Firestore Map数据转换的方法:
import 'package:cloud_firestore/cloud_firestore.dart'; // 嵌套的地址类 class Address { final String street; final String city; Address({required this.street, required this.city}); // 从Firestore的Map结构转成Address对象 factory Address.fromMap(Map<String, dynamic> map) { return Address( street: map['street'] as String, city: map['city'] as String, ); } } // 主用户类 class User { final String id; final String name; final int age; final Address address; User({required this.id, required this.name, required this.age, required this.address}); // 从Firestore文档快照转成User对象 factory User.fromFirestore(DocumentSnapshot doc) { final data = doc.data() as Map<String, dynamic>; return User( id: doc.id, name: data['name'] as String, age: data['age'] as int, // 处理嵌套的Address数据 address: Address.fromMap(data['address'] as Map<String, dynamic>), ); } }
使用示例:
// 读取单个文档 final docSnapshot = await FirebaseFirestore.instance.collection('users').doc('user1').get(); final user = User.fromFirestore(docSnapshot); // 读取整个集合 final querySnapshot = await FirebaseFirestore.instance.collection('users').get(); final users = querySnapshot.docs.map((doc) => User.fromFirestore(doc)).toList();
方法二:使用json_serializable自动生成转换代码
对于嵌套层级多、结构复杂的数据,手动写转换逻辑容易出错,用插件自动生成更高效:
- 先在
pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter cloud_firestore: ^latest_version json_annotation: ^latest_version dev_dependencies: build_runner: ^latest_version json_serializable: ^latest_version
- 定义带注解的PODO类:
import 'package:json_annotation/json_annotation.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; part 'user.g.dart'; // 嵌套地址类 @JsonSerializable() class Address { final String street; final String city; Address({required this.street, required this.city}); factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json); Map<String, dynamic> toJson() => _$AddressToJson(this); } // 主用户类 @JsonSerializable() class User { final String id; final String name; final int age; final Address address; User({required this.id, required this.name, required this.age, required this.address}); // 从Firestore快照转换:先把文档ID加入数据,再用自动生成的fromJson方法 factory User.fromFirestore(DocumentSnapshot doc) { final data = doc.data() as Map<String, dynamic>; data['id'] = doc.id; return User.fromJson(data); } factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); }
- 运行命令生成转换代码:
在终端执行:
flutter pub run build_runner build
如果需要实时监听文件变化自动更新代码,用:
flutter pub run build_runner watch
- 使用方式和手动转换一致:
final docSnapshot = await FirebaseFirestore.instance.collection('users').doc('user1').get(); final user = User.fromFirestore(docSnapshot);
额外注意点
- 如果Firestore中的字段名和PODO属性名不一致,可以用
@JsonKey(name: 'firestore_field_name')注解映射,比如:
@JsonKey(name: 'user_full_name') final String name;
- 处理可选字段时,可给属性添加
?或者设置默认值,避免null报错。
内容的提问来源于stack exchange,提问作者Shubham Srivastava
相关产品推荐
相关产品推荐

