Flutter MongoDB Realm数据库集成插件flutter_mongodb_realm的使用

Flutter MongoDB Realm数据库集成插件flutter_mongodb_realm的使用

简介

flutter_mongodb_realm 是一个非官方的Flutter插件,用于在Android、iOS和Web平台上使用MongoDB Realm服务。通过这个插件,开发者可以轻松地与MongoDB Atlas数据库进行交互,并实现用户认证、数据操作等功能。

入门指南

1. 添加依赖

pubspec.yaml文件中添加flutter_mongodb_realm依赖:

dependencies:
  flutter_mongodb_realm: ^最新版本号
2. 最低要求
  • Android 5.0 (API 21)
  • iOS 13.0
3. 初始化

main.dart文件中初始化RealmApp

import 'package:flutter/material.dart';
import 'package:flutter_mongodb_realm/flutter_mongo_realm.dart';

void main() async {
  // 确保Flutter绑定已初始化
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化MongoDB Realm应用,替换为你的应用ID
  await RealmApp.init('your_app_id');
  
  runApp(MyApp());
}

使用示例

1. 创建客户端

定义一个MongoRealmClient实例来与数据库进行交互:

final client = MongoRealmClient();
2. 认证
2.1 匿名登录
CoreRealmUser? mongoUser = await app.login(Credentials.anonymous());
2.2 邮箱/密码登录
CoreRealmUser? mongoUser = await app.login(
  Credentials.emailPassword(email: 'user@example.com', password: 'password'));
2.3 Facebook登录

首先需要在Flutter项目中配置Facebook登录相关的包(如flutter_facebook_auth),然后使用以下代码进行登录:

CoreRealmUser? mongoUser = await app.login(
  Credentials.facebook(accessToken));
2.4 Google登录

Google登录需要在Firebase和Google Cloud Platform上进行配置,获取客户端ID和SHA-1指纹。具体步骤如下:

  1. 在Firebase创建项目并添加Web应用。
  2. 在Google Cloud Platform中创建OAuth 2.0客户端ID。
  3. 在MongoDB Realm中配置Google认证,使用Web客户端ID和客户端密钥。
  4. 在Flutter中使用google_sign_in包进行登录:
GoogleSignIn _googleSignIn = GoogleSignIn(
  scopes: ['email'],
  clientId: 'YOUR_APP_ID.apps.googleusercontent.com'
);

var account = await _googleSignIn.signIn();
var serverAuthCode = account?.serverAuthCode;

CoreRealmUser? mongoUser = await app.login(GoogleCredential2(serverAuthCode!));
2.5 Apple ID登录

使用sign_in_with_apple包进行Apple ID登录:

final appleResult = await AppleSignIn.performRequests([
  AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
]);

if (appleResult.error == null) {
  var idToken = String.fromCharCodes(appleResult.credential.identityToken);
  CoreRealmUser? mongoUser = await app.login(Credentials.apple(idToken));
}
2.6 自定义JWT登录
CoreRealmUser? mongoUser = await app.login(Credentials.jwt('your_jwt_token'));
2.7 自定义认证函数
MongoDocument payload = MongoDocument({
  "username": "bob"
});

CoreRealmUser? mongoUser = await app.login(Credentials.function(payload));
3. 数据库操作
3.1 获取集合
final collection = client.getDatabase('test').getCollection('my_collection');
3.2 插入文档
await collection.insertOne(MongoDocument({
  "time": DateTime.now().millisecondsSinceEpoch,
  "username": "moshe",
  "grades": [90, 98],
}));

// 或者插入多个文档
await collection.insertMany([
  MongoDocument({
    "time": DateTime.now().millisecondsSinceEpoch,
    "username": "moshe",
    "grades": [90, 98],
  }),
  MongoDocument({
    "time": DateTime.now().millisecondsSinceEpoch,
    "username": "adiel",
    "age": [77, 55, 91],
  }),
]);
3.3 查询文档
// 查询所有文档
var docs = await collection.find();

// 带过滤条件的查询
var filteredDocs = await collection.find(
  filter: {
    "year": QueryOperator.gt(2010)..lte(2014),
  },
  options: RemoteFindOptions(
    projection: {
      "title": ProjectionValue.INCLUDE,
      "rated": ProjectionValue.INCLUDE,
      "year": ProjectionValue.INCLUDE,
    },
    limit: 70,
    sort: {
      "year": OrderValue.ASCENDING,
    }
  ),
);

// 查询单个文档
var doc = await collection.findOne(
  filter: {
    "name": "naama",
  },
);
3.4 删除文档
// 删除所有文档
var deletedDocs = await collection.deleteMany({});

// 删除符合条件的第一个文档
var deletedDoc = await collection.deleteOne({"age": 24});

// 删除符合条件的所有文档
var deletedDocs = await collection.deleteMany({"age": QueryOperator.gte(24)});
3.5 更新文档
// 更新符合条件的第一个文档
await collection.updateOne(
  filter: {
    "_id": ObjectId('601204a6a80d3fbab2e3a73f'),
  },
  update: UpdateSelector.set({
    "age": 26,
  }),
);

// 更新符合条件的所有文档
await collection.updateMany(
  filter: {
    "name": "adiel",
  },
  update: UpdateOperator.inc({
    "age": -2,
    "quantity": 30,
  }),
);
3.6 监听文档变化
final stream = collection.watch(ids: ["22"], asObjectIds: false);

stream.listen((event) {
  var fullDocument = MongoDocument.parse(event);
  print("文档 '${fullDocument.map["_id"]}' 已更改");
});
3.7 聚合操作
List<PipelineStage> pipeline = [
  PipelineStage.sample(2),
];

var list = await collection.aggregate(pipeline);
print(list.length);
4. 调用Realm函数
var result = await client.callFunction("sum", args: [3, 4], requestTimeout: 60000);
5. 认证状态监听

使用StreamBuilder监听用户的认证状态变化:

StreamBuilder _authBuilder(BuildContext context) {
  return StreamBuilder(
    stream: app.authListener(),
    builder: (context, AsyncSnapshot snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.none:
        case ConnectionState.waiting:
          return Scaffold(body: Center(child: CircularProgressIndicator()));
        case ConnectionState.active:
          if (snapshot.error != null) {
            return Container(
              alignment: Alignment.center,
              child: Text(snapshot.error.toString()),
            );
          }
          return snapshot.hasData ? HomeScreen() : LoginScreen();
        default:
          return LoginScreen();
      }
    },
  );
}

完整示例Demo

下面是一个完整的示例应用程序,展示了如何使用flutter_mongodb_realm插件进行基本的数据库操作和用户认证。

import 'package:flutter/material.dart';
import 'package:flutter_mongodb_realm/flutter_mongo_realm.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await RealmApp.init('your_app_id');
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final MongoRealmClient client = MongoRealmClient();
  final RealmApp app = RealmApp();

  [@override](/user/override)
  void initState() {
    super.initState();
    init();
  }

  Future<void> init() async {
    try {
      await app.login(Credentials.anonymous());
      watchData();
    } catch (e) {
      print("Error initializing: $e");
    }
  }

  Future<void> insertData() async {
    var collection = client.getDatabase("test").getCollection("my_collection");

    try {
      await collection.insertMany([
        MongoDocument({
          "time": DateTime.now().millisecondsSinceEpoch,
          "username": "moshe",
          "grades": [90, 98],
        }),
        MongoDocument({
          "time": DateTime.now().millisecondsSinceEpoch,
          "username": "adiel",
          "age": [77, 55, 91],
        }),
      ]);
      print("Data inserted successfully");
    } catch (e) {
      debugPrint("Error inserting data: $e");
    }
  }

  Future<void> fetchData() async {
    var collection = client.getDatabase("test").getCollection("my_collection");

    try {
      var docs = await collection.find(
        filter: {
          "name": "naama",
        },
      );

      docs.forEach((doc) {
        print(doc.get("_id"));
      });
    } catch (e) {
      debugPrint("Error fetching data: $e");
    }
  }

  void watchData() {
    var myCollection = client.getDatabase("test").getCollection("my_collection");

    try {
      final stream = myCollection.watch(ids: ["22"], asObjectIds: false);
      stream.listen((event) {
        var fullDocument = MongoDocument.parse(event);
        print("文档 '${fullDocument.map["_id"]}' 已更改");
      });
    } catch (e) {
      print("Error watching data: $e");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: _authBuilder(context),
    );
  }

  StreamBuilder _authBuilder(BuildContext context) {
    return StreamBuilder(
      stream: app.authListener(),
      builder: (context, AsyncSnapshot snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
            return Scaffold(body: Center(child: CircularProgressIndicator()));
          case ConnectionState.active:
            if (snapshot.error != null) {
              return Container(
                alignment: Alignment.center,
                child: Text(snapshot.error.toString()),
              );
            }
            return snapshot.hasData ? HomeScreen() : LoginScreen();
          default:
            return LoginScreen();
        }
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            await insertData();
          },
          child: Text('Insert Data'),
        ),
      ),
    );
  }
}

class LoginScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            try {
              await app.login(Credentials.anonymous());
            } catch (e) {
              print("Login error: $e");
            }
          },
          child: Text('Login Anonymously'),
        ),
      ),
    );
  }
}

更多关于Flutter MongoDB Realm数据库集成插件flutter_mongodb_realm的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


当然,下面是一个关于如何在Flutter项目中集成并使用flutter_mongodb_realm插件来连接MongoDB Realm数据库的示例代码。

首先,确保你已经在你的Flutter项目中添加了flutter_mongodb_realm依赖。打开你的pubspec.yaml文件,并添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_mongodb_realm: ^最新版本号 # 请替换为实际的最新版本号

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

接下来,你需要配置MongoDB Realm应用程序。确保你已经在MongoDB Realm上创建了一个应用程序,并获取了应用程序ID和API密钥。

配置Realm应用

在Flutter项目中,你需要配置Realm应用。你可以在main.dart或任何合适的地方进行配置。

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

void main() {
  // 配置Realm应用
  RealmApp.configure(appId: '你的应用程序ID', apiKey: '你的API密钥');

  runApp(MyApp());
}

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

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

class _HomeScreenState extends State<HomeScreen> {
  late Realm realm;

  @override
  void initState() {
    super.initState();

    // 打开Realm实例
    Realm.open({}).then((openedRealm) {
      setState(() {
        realm = openedRealm;
      });
    }).catchError((error) {
      print('Failed to open Realm: $error');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter MongoDB Realm 示例'),
      ),
      body: Center(
        child: realm.isClosed
            ? Text('正在打开Realm...')
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('Realm已打开!'),
                  ElevatedButton(
                    onPressed: () async {
                      // 示例:插入数据
                      await realm.write(() async {
                        final myObject = realm.createObject('MyObject', {
                          'name': 'Flutter Demo',
                          'value': 42,
                        });
                      });
                      print('数据已插入: ${myObject.toJson()}');
                    },
                    child: Text('插入数据'),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      // 示例:查询数据
                      final results = await realm.objects('MyObject').findAll();
                      print('查询结果: ${results.map((obj) => obj.toJson()).toList()}');
                    },
                    child: Text('查询数据'),
                  ),
                ],
              ),
      ),
    );
  }

  @override
  void dispose() {
    // 关闭Realm实例
    realm.close();
    super.dispose();
  }
}

注意事项

  1. Realm模型:在上面的示例中,我们假设在MongoDB Realm中已经定义了一个名为MyObject的模型。你需要确保这个模型已经存在,并且字段与你在代码中使用的字段匹配。

  2. 权限:确保你的MongoDB Realm应用程序的权限设置允许你的应用进行读写操作。

  3. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑来应对各种可能的异常情况,比如网络问题、认证失败等。

  4. 清理资源:在dispose方法中关闭Realm实例是一个好的实践,以避免内存泄漏。

  5. 更新依赖:始终确保你使用的是flutter_mongodb_realm的最新版本,以获取最新的功能和修复。

希望这个示例代码能帮助你成功地在Flutter项目中集成MongoDB Realm数据库!

回到顶部