Flutter数据模型与Firestore集成插件katana_model_firestore的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter数据模型与Firestore集成插件katana_model_firestore的使用

介绍

在Flutter开发中,数据读写实现可能比较繁琐。为了简化这一过程,katana_model插件提供了一种简洁的方式来处理数据模型与Firestore的集成。本文将详细介绍如何使用katana_model_firestore插件来集成Flutter数据模型与Firestore。

安装

首先,确保你已经在项目中添加了必要的依赖:

dependencies:
  katana_model: ^latest_version
  katana_model_firestore: ^latest_version

如果你还需要本地数据库支持,可以添加:

dependencies:
  katana_model_local: ^latest_version

数据模型实现

文档模型

创建一个文档模型类,继承自DocumentBase<T>,并实现fromMaptoMap方法:

class DynamicMapDocument extends DocumentBase<Map<String, dynamic>> {
  DynamicMapDocument(super.modelQuery);

  @override
  Map<String, dynamic> fromMap(Map<String, dynamic> map) => map;

  @override
  Map<String, dynamic> toMap(Map<String, dynamic> value) => value;
}

集合模型

创建一个集合模型类,继承自CollectionBase<TDocument>,并实现create方法:

class DynamicMapCollection extends CollectionBase<DynamicMapDocument> {
  DynamicMapCollection(super.modelQuery);

  @override
  DynamicMapDocument create([String? id]) {
    return DynamicMapDocument(modelQuery.create(id));
  }
}

使用示例

初始化ModelAdapterScope

在应用启动时,初始化ModelAdapterScope并选择合适的适配器(例如,FirestoreModelAdapter):

import 'package:flutter/material.dart';
import 'package:katana_model/katana_model.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ModelAdapterScope(
      adapter: FirestoreModelAdapter(options: DefaultFirebaseOptions.currentPlatform),
      child: MaterialApp(
        home: const ModelPage(),
        title: "Flutter Demo",
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
      ),
    );
  }
}

创建、加载、更新和删除数据

以下是一个完整的示例,展示了如何使用上述模型进行CRUD操作:

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:katana_model/katana_model.dart';

class ModelDocument extends DocumentBase<Map<String, dynamic>> {
  ModelDocument(super.modelQuery);

  @override
  Map<String, dynamic> fromMap(Map<String, dynamic> map) => map;

  @override
  Map<String, dynamic> toMap(Map<String, dynamic> value) => value;
}

class ModelCollection extends CollectionBase<ModelDocument> {
  ModelCollection(super.modelQuery);

  @override
  ModelDocument create([String? id]) {
    return ModelDocument(modelQuery.create(id));
  }
}

class ModelPage extends StatefulWidget {
  const ModelPage({super.key});

  @override
  State<StatefulWidget> createState() => ModelPageState();
}

class ModelPageState extends State<ModelPage> {
  final collection = ModelCollection(const CollectionModelQuery("/user"));

  @override
  void initState() {
    super.initState();
    collection.addListener(_handledOnUpdate);
    collection.load();
  }

  void _handledOnUpdate() {
    setState(() {});
  }

  @override
  void dispose() {
    super.dispose();
    collection.removeListener(_handledOnUpdate);
    collection.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Flutter Demo")),
      body: FutureBuilder(
        future: collection.loading ?? Future.value(),
        builder: (context, snapshot) {
          if (snapshot.connectionState != ConnectionState.done) {
            return const Center(child: CircularProgressIndicator());
          }
          return ListView(
            children: [
              ...collection.mapListenable((doc) {
                return ListTile(
                  title: Text(doc.value?["count"].toString() ?? "0"),
                  trailing: IconButton(
                    onPressed: () {
                      doc.delete();
                    },
                    icon: const Icon(Icons.delete),
                  ),
                  onTap: () {
                    doc.save({
                      "count": Random().nextInt(100),
                    });
                  },
                );
              }),
            ],
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          final doc = collection.create();
          doc.save({
            "count": Random().nextInt(100),
          });
        },
      ),
    );
  }
}

切换数据库

通过更改传递给ModelAdapterScopeModelAdapter,你可以轻松地从模拟数据切换到本地数据库或Firestore。例如:

// 使用本地数据库
ModelAdapterScope(
  adapter: const LocalModelAdapter(),
  child: MaterialApp(
    home: const ScopedTestPage(),
    title: "Flutter Demo",
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
  ),
)

// 使用Firestore数据库
ModelAdapterScope(
  adapter: FirestoreModelAdapter(options: DefaultFirebaseOptions.currentPlatform),
  child: MaterialApp(
    home: const ScopedTestPage(),
    title: "Flutter Demo",
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
  ),
)

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

1 回复

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


在Flutter项目中,将数据模型与Firestore集成通常涉及几个步骤,包括定义数据模型、配置Firestore、使用插件(如katana_model_firestore)进行数据操作等。虽然katana_model_firestore这个具体的插件可能并不广为人知(在Flutter社区中更常见的可能是cloud_firestore),但我们可以基于一般的Flutter和Firestore集成流程,给出一个类似的代码案例。

假设我们使用cloud_firestore插件(这是Flutter官方支持的Firestore插件)来实现类似的功能,以下是一个基本的代码案例:

1. 添加依赖

首先,在你的pubspec.yaml文件中添加cloud_firestore依赖:

dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^x.y.z  # 替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 定义数据模型

定义一个简单的数据模型,比如一个用户模型:

class User {
  String id;
  String name;
  int age;

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

  // 从Map转换为User对象
  factory User.fromMap(Map<String, dynamic> map) {
    return User(
      id: map['id'] as String,
      name: map['name'] as String,
      age: map['age'] as int,
    );
  }

  // 将User对象转换为Map
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
    };
  }
}

3. 配置Firestore

在你的Flutter应用中初始化Firestore:

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  FirebaseFirestore.instance.settings = Settings(persistenceEnabled: true);
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

4. 使用Firestore进行数据操作

在你的主屏幕或某个组件中,添加添加、读取、更新和删除(CRUD)操作:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'user_model.dart';  // 假设你的User模型文件名为user_model.dart

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final CollectionReference<Map<String, dynamic>> usersCollection =
      FirebaseFirestore.instance.collection('users');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Firestore CRUD'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            ElevatedButton(
              onPressed: () => addUser(),
              child: Text('Add User'),
            ),
            ElevatedButton(
              onPressed: () => readUsers(),
              child: Text('Read Users'),
            ),
            // 可以添加更新和删除按钮的类似实现
          ],
        ),
      ),
    );
  }

  void addUser() {
    User user = User(id: uuid.v4(), name: 'John Doe', age: 30);  // 使用uuid库生成唯一ID
    usersCollection.add(user.toMap());
  }

  void readUsers() async {
    QuerySnapshot<Map<String, dynamic>> snapshot = await usersCollection.get();
    List<User> users = snapshot.docs.map((doc) => User.fromMap(doc.data() as Map<String, dynamic>)).toList();
    // 在这里处理users列表,比如显示在ListView中
  }

  // 你可以在这里添加updateUser和deleteUser函数来实现更新和删除操作
}

注意:上面的代码示例中,uuid.v4()用于生成唯一ID,你可能需要添加uuid依赖到你的pubspec.yaml文件中。

总结

虽然katana_model_firestore插件的具体用法可能有所不同,但上述代码提供了一个使用cloud_firestore插件在Flutter项目中集成Firestore并进行基本CRUD操作的示例。如果你确实需要使用katana_model_firestore,建议查阅该插件的官方文档或GitHub仓库以获取具体的用法和示例。

回到顶部