Flutter Firestore数据转换插件firestore_converter的使用
Flutter Firestore数据转换插件firestore_converter的使用
介绍
firestore_converter
是一个用于简化 Firestore 数据模型与 Dart 类之间转换的插件。通过使用 [@FirestoreConverter](/user/FirestoreConverter)
注解,可以自动生成 withConverter
实现,从而减少样板代码。它最好与其他注解库(如 freezed
或 json_serializable
)一起使用,但并不是必需的。
减少样板代码
Before:
part 'example.freezed.dart';
part 'example.g.dart';
[@freezed](/user/freezed)
class Example<T> with _$Example<T> {
factory Example(int a) = _Example;
factory Example.fromJson(Map<String, Object?> json) => _$ExampleFromJson(json);
}
CollectionReference<Example> exampleCollection([String path = 'examples']) {
return FirebaseFirestore.instance
.collection(path)
.withConverter<Example>(
fromFirestore: (snapshot, _) => Example.fromJson(snapshot.data()!),
toFirestore: (instance, _) => instance.toJson(),
);
}
DocumentReference<Example> exampleDoc({String path = 'examples', required String docId}) {
return FirebaseFirestore.instance
.doc('$path/$docId')
.withConverter<Example>(
fromFirestore: (snapshot, _) => Example.fromJson(snapshot.data()!),
toFirestore: (instance, _) => instance.toJson(),
);
}
After:
part 'example.firestore_converter.dart';
part 'example.freezed.dart';
part 'example.g.dart';
[@freezed](/user/freezed)
[@FirestoreConverter](/user/FirestoreConverter)(defaultPath: 'examples')
class Example<T> with _$Example<T> {
factory Example(int a) = _Example;
factory Example.fromJson(Map<String, Object?> json) => _$ExampleFromJson(json);
}
安装
-
安装
build_runner
以运行代码生成:flutter pub add dev:build_runner
-
安装
firestore_converter_generator
作为开发依赖:flutter pub add dev:firestore_converter_generator
-
安装
firestore_converter
作为普通依赖:flutter pub add firestore_converter
升级指南(适用于版本1.0.8之前的用户)
如果你之前使用的是 firestore_converter
版本1.0.8之前的版本,请按照以下步骤进行升级:
-
移除旧的依赖:
flutter pub remove firestore_converter_annotation flutter pub remove firestore_converter
-
添加新的依赖:
flutter pub add dev:build_runner flutter pub add dev:firestore_converter_generator flutter pub add firestore_converter
-
在源代码中替换导入语句:
- 将
import 'package:firestore_converter_annotation/firestore_converter_annotation.dart';
替换为:import 'package:firestore_converter/firestore_converter.dart';
- 将
使用方法
在数据类上使用 [@FirestoreConverter](/user/FirestoreConverter)(defaultPath: 'someDataPathInFirestore')
注解,将生成两个辅助函数:
${modelClassName}Collection
${modelClassName}Doc
请注意,这些是函数而不是成员,因为目前无法通过代码生成向模型类添加静态函数。模型名称的首字母将被转换为小写,以符合 Dart 的函数命名规范。
实现 fromJson
和 toJson
firestore_converter
依赖于 fromJson
和 toJson
方法的存在或实现。你可以使用 freezed
、json_serializable
或其他注解库来方便地实现这两个方法。当然,你也可以手动实现它们,但这可能会违背使用代码生成的目的。
注意事项
- 必须启用或实现 JSON 转换的
fromJson
和toJson
方法。 - 使用给定的路径作为集合和文档的默认参数。
- 不支持
build.yaml
中的默认设置,因为路径设置是针对每个模型类的。
示例:使用 firestore_converter
和 freezed
定义你的模型类,例如 example.dart
:
part 'example.firestore_converter.dart';
part 'example.freezed.dart';
part 'example.g.dart';
[@freezed](/user/freezed)
[@FirestoreConverter](/user/FirestoreConverter)(defaultPath: 'examples')
class Example<T> with _$Example<T> {
factory Example(int a) = _Example;
factory Example.fromJson(Map<String, Object?> json) => _$ExampleFromJson(json);
}
运行代码生成以生成 example.firestore_converter.dart
:
flutter pub run build_runner build --delete-conflicting-outputs
开始使用:
// 现在可以轻松创建完全类型的 CollectionReferences、DocumentReferences 或 SnapShot 对象:
CollectionReference<Example> col1 = exampleCollection().orderBy('date', descending: true); // 默认路径为注解中的 'examples'
CollectionReference<Example> col2 = exampleCollection('some_other_path').orderBy('a', descending: true);
DocumentReference<Example> doc1 = exampleDoc(docId: 'exampleId'); // 默认路径为注解中的 'examples'
DocumentReference<Example> doc2 = exampleDoc(path: 'some_other_path', docId: 'exampleId');
// 检索某些文档数据
var myDoc = exampleDoc(path: 'some_other_path', docId: 'exampleId').get();
// 直接从快照访问类型化的成员
debugPrint(myDoc.data().a);
完整示例 Demo
以下是一个完整的示例,展示了如何使用 firestore_converter
和 freezed
来创建一个简单的 Flutter 应用程序,该应用程序连接到 Firestore 并显示用户列表:
// 这个示例需要 Firestore 模拟器正在运行!
// 通过以下命令启动:
// firebase emulators:start --project demo-example
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:faker/faker.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_firestore/firebase_ui_firestore.dart';
import 'package:firestore_converter/firestore_converter.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'main.firestore_converter.dart';
part 'main.freezed.dart';
part 'main.g.dart';
var faker = Faker();
[@FirestoreConverter](/user/FirestoreConverter)(defaultPath: 'users')
[@freezed](/user/freezed)
class User with _$User {
factory User({
required String name,
required String email,
required int salary,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 这个示例需要 Firestore 模拟器正在运行!
// 通过以下命令启动:
// firebase emulators:start --project demo-example
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: 'not-required-for-emulator',
appId: 'not-required-for-emulator',
messagingSenderId: 'not-required-for-emulator',
projectId: 'demo-example',
),
);
try {
FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
} catch (e) {
print(e);
rethrow;
}
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
floatingActionButton: Builder(builder: (context) {
return FloatingActionButton(
key: const Key('addButton'),
onPressed: () async {
var newUser = User(
email: faker.internet.email(),
name: faker.person.name(),
salary: faker.randomGenerator.integer(100000),
);
try {
await userCollection().add(newUser);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('New user added'),
key: Key('snackbar'),
));
} catch (e) {
debugPrint(e.toString());
rethrow;
}
},
child: const Icon(Icons.add),
);
}),
body: FirestoreListView<User>(
query: userCollection().orderBy('name'),
itemBuilder: (context, snapshot) => Card(
child: ListTile(
key: Key(snapshot.data().name),
title: Text(snapshot.data().name),
subtitle: Row(
children: [
Text(snapshot.data().email),
const Expanded(child: Center()),
Text(snapshot.data().salary.toString()),
],
),
),
),
),
),
);
}
}
更多关于Flutter Firestore数据转换插件firestore_converter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Firestore数据转换插件firestore_converter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 firestore_converter
插件在 Flutter 中进行 Firestore 数据转换的示例代码。firestore_converter
插件允许你将 Firestore 数据与 Dart 模型之间进行无缝转换,特别是当你使用 freezed
或 json_serializable
生成的 Dart 模型时。
首先,确保你的 pubspec.yaml
文件中包含以下依赖项:
dependencies:
flutter:
sdk: flutter
cloud_firestore: ^3.1.0
firestore_converter: ^0.4.0+2 # 请检查最新版本号
json_annotation: ^4.0.1 # 如果你使用 json_serializable
然后,运行 flutter pub get
来获取这些依赖项。
示例模型
假设你有一个简单的用户模型 User
,使用 json_serializable
来生成 fromJson
和 toJson
方法:
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
final String id;
final String name;
final int age;
User({required this.id, required this.name, required this.age});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
生成 user.g.dart
文件:
flutter pub run build_runner build
使用 Firestore 和 firestore_converter
接下来,在你的 Flutter 应用中使用 firestore_converter
将 Firestore 数据转换为 User
对象。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firestore_converter/firestore_converter.dart';
import 'user.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化 Firestore 实例
final Firestore firestore = Firestore.instance;
// 注册 User 模型的转换器
FirestoreConverter.useConverters = true;
FirestoreConverter.registerFromDocument<User>((snapshot, options) => User.fromJson(snapshot.data()! as Map<String, dynamic>));
FirestoreConverter.registerToDocument<User>((user) => user.toJson());
// 添加一个示例用户到 Firestore
await firestore.collection('users').add(<String, dynamic>{
'name': 'Alice',
'age': 30,
});
// 从 Firestore 读取用户数据
final QuerySnapshot<Map<String, dynamic>> snapshot = await firestore.collection('users').get();
final List<User> users = snapshot.docs.map((doc) => User.fromJson(doc.data()! as Map<String, dynamic>)).toList();
// 输出用户数据
users.forEach((user) => print('User: ${user.name}, Age: ${user.age}'));
}
注意:在上面的代码中,我们手动将 Firestore 数据转换为 User
对象。然而,通过使用 firestore_converter
的注册功能,我们可以让 Firestore 自动处理这些转换。但由于 firestore_converter
插件的 API 可能在不同版本中有所不同,这里我们手动展示了转换过程。实际上,如果插件支持,你可以利用插件的自动转换功能来简化代码。
为了利用 firestore_converter
的自动转换功能(如果支持),你可能需要调整代码以使用插件提供的封装方法,但具体实现依赖于插件的当前版本和 API。由于 firestore_converter
的 API 可能会变化,请参考其官方文档和示例以获取最新和最准确的用法。
希望这能帮助你理解如何在 Flutter 中使用 firestore_converter
插件进行 Firestore 数据转换!