Flutter Firestore数据转换插件firestore_converter_generator的使用

Flutter Firestore数据转换插件firestore_converter_generator的使用

此包用于在Flutter中与Firestore进行数据转换。你可以通过查看firestore_converter包的文档和安装说明来获取更多信息。

示例代码

// 此示例需要运行Firebase模拟器
// 运行命令:
// 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/foundation.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(defaultPath: 'users')
@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();

  // 此示例需要运行Firebase模拟器
  // 运行命令:
  // 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
  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()),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

完整示例Demo

主文件 main.dart

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/foundation.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(defaultPath: 'users')
@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();

  // 需要运行Firebase模拟器
  // 运行命令:
  // 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
  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()),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

main.firestore_converter.dart 文件

// 自动生成的文件
import 'package:firestore_converter/firestore_converter.dart';
import 'main.freezed.dart';

extension FirestoreUserConverter on CollectionReference {
  CollectionReference<User> get userCollection => this.withConverter(
        fromFirestore: User.fromJson,
        toFirestore: (user, _) => user.toJson(),
      );
}

main.freezed.dart 文件

// 自动生成的文件
import 'package:freezed_annotation/freezed_annotation.dart';

part of 'main.dart';

@freezed
abstract class User with _$User {
  factory User({
    required String name,
    required String email,
    required int salary,
  }) = _User;
}

main.g.dart 文件

// 自动生成的文件
import 'package:firestore_converter/firestore_converter.dart';
import 'main.freezed.dart';

User _$UserFromJson(Map<String, dynamic> json) => User.fromJson(json);

更多关于Flutter Firestore数据转换插件firestore_converter_generator的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Firestore数据转换插件firestore_converter_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用firestore_converter_generator插件进行数据转换的代码案例。firestore_converter_generator是一个用于生成Firestore数据模型的Dart代码生成器,它可以帮助你将Firestore的数据模型与Dart类进行无缝转换。

步骤1:添加依赖

首先,在你的pubspec.yaml文件中添加firestore_converter_generator及其依赖项:

dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^3.1.0

dev_dependencies:
  build_runner: ^2.1.4
  firestore_converter_generator: ^3.0.0  # 请根据最新版本进行调整

步骤2:定义Firestore数据模型

创建一个Dart文件(例如models/user_model.dart),并定义你的Firestore数据模型。这里假设我们有一个简单的用户模型:

// models/user_model.dart
import 'package:json_annotation/json_annotation.dart';

part 'user_model.g.dart';

@JsonSerializable()
class UserModel {
  String id;
  String name;
  int age;

  UserModel({required this.id, required this.name, required this.age});

  // 从JSON生成UserModel对象
  factory UserModel.fromJson(Map<String, dynamic> json) => _$UserModelFromJson(json);

  // 将UserModel对象转换为JSON
  Map<String, dynamic> toJson() => _$UserModelToJson(this);
}

注意:part 'user_model.g.dart'; 这一行很重要,因为代码生成器会生成这个文件。

步骤3:生成转换器代码

在项目根目录下运行以下命令来生成转换器代码:

flutter pub run build_runner build --delete-conflicting-outputs

这个命令会生成user_model.g.dart文件,其中包含了fromJsontoJson方法的实现。

步骤4:使用Firestore和转换器

现在你可以在你的Flutter应用中使用Firestore和这些转换器了。例如,从Firestore读取用户数据:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'models/user_model.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Firestore Converter Demo')),
        body: FirestoreDemo(),
      ),
    );
  }
}

class FirestoreDemo extends StatefulWidget {
  @override
  _FirestoreDemoState createState() => _FirestoreDemoState();
}

class _FirestoreDemoState extends State<FirestoreDemo> {
  late Stream<List<UserModel>> usersStream;

  @override
  void initState() {
    super.initState();
    usersStream = FirebaseFirestore.instance
        .collection('users')
        .snapshots()
        .map((snapshot) =>
            snapshot.docs.map((doc) => UserModel.fromJson(doc.data() as Map<String, dynamic>)).toList());
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<UserModel>>(
      stream: usersStream,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              UserModel user = snapshot.data![index];
              return ListTile(
                title: Text('Name: ${user.name}, Age: ${user.age}'),
              );
            },
          );
        } else {
          return Text('No data');
        }
      },
    );
  }
}

在这个例子中,我们创建了一个简单的Flutter应用,它从Firestore的users集合中读取数据,并使用UserModel类来解析这些数据。

总结

通过使用firestore_converter_generator,你可以轻松地将Firestore的数据模型转换为Dart类,并在你的Flutter应用中使用这些类。这不仅简化了数据解析过程,还提高了代码的可读性和可维护性。

回到顶部