「Flexible Sync」でデータを同期してみよう
はじめに
前回で、ひと通り機能の実装は完了しました。本連載が始まってから約1年が経過し、MongoDB Cloudのインターフェースも変わりRealmにも色々と機能が追加されています。それに応じて、Realmライブラリのバージョンも上がっています。
最終回となる今回は、前回までに実装した機能を最新のライブラリに置き換えて、再実装していきます。また、連載当初にはなかった新しい同期機能“Flexible Sync”を試してみます。
Realmライブラリの更新
2022年10月12日現在のRealmライブラリの最新バージョン「10.17.0」をインストールします。ライブラリはNuGet Galleryから確認できます。
インストール
本手順では、Visual StudioのNugetパッケージマネージャーコンソールから、最新のRealmライブラリに置き換える方法を説明します。
- Visual Studioでモバイルアプリのソリューションを開きます(※GitLabにてコードを公開)。
- メニューバーから、[ツール] - [NuGet パッケージ マネージャー] - [パッケージ マネージャー コンソール] をクリックします。
- パッケージマネージャーコンソールが表示されるので、以下のコマンドを入力し、現在のRealmライブラリのバージョンを確認します。
PM> Get-Package -Filter Realm | Select-Object Id, Version Id Version -- ------- Realm 10.7.1
- 以下のコマンドを入力し、最新バージョンをインストールします。
PM> Install-Package Realm -Version 10.17.0
- もう一度Get-Packageコマンドを実行し、最新バージョンに置き換わっていることを確認します。
PM> Get-Package -Filter Realm | Select-Object Id, Version Id Version -- ------- Realm 10.17.0
以上で、インストールは完了です。
SyncConfigurationの警告
TopFragment.csとEditFragment.cs内で、Realmライブラリの「SyncConfiguration」というクラスのオブジェクトを作成しています。新バージョンインストール後にその部分を確認すると「‘SyncConfiguration’は旧型式です」という警告が表示されるようになります。
これは、MongoDB RealmのDevice Syncのタイプとして、Partitionだけではなく、新たに「Flexible」という仕様が加わったことによります。SyncConfigurationクラスは引き続きPartitionタイプの同期に対応しますが、C#コードからはどちらのタイプの同期なのかがわかり辛いため、新たに PartitionSysncConfigurationクラスの使用が推奨されています。
コードの書き換えと実行
SyncConfigurationは5箇所で使用しています。それらをすべてPartitionSyncConfigurationに書き換えます。
また、モバイル端末内のRealm データベースを取得するためのRealm.GetInstance関数を、非同期版のRealm.GetInstanceAsyncに置き換えます。実は、アプリにログイン後のトップ画面初回表示時に商品リストが更新されないという問題がありましたが、非同期にすることで解決します。
●TopFragment.cs L60 〜 63// Realm から商品の一覧を取得する using Realm publicRealm = await Realm.GetInstanceAsync( new PartitionSyncConfiguration(((MainActivity)this.Activity).PUBLIC_PARTITION, app.CurrentUser, Path.Combine(((MainActivity)this.Activity).realmDir, "public.realm")));
上記と同様の書き換えを、以下の行にも適用します。
- TopFragment.cs L100 〜 102
- AddFragment.cs L54 〜 56
・非同期関数のためL39にasyncを追加します。protected async void AddInventory(object sender, EventArgs e)
- EditFragment.cs L72 〜 74
・非同期関数のためL57にasyncを追加します。protected async void AddInventory(object sender, EventArgs e)
- EditFragment.cs L106 〜 108
・非同期関数のためL102のラムダ式にasyncを追加します。builder.SetPositiveButton("YES", async (sender, e) =>
これで、コードの書き換えは完了です(※ここまでのコードはGitLabからダウンロード可能)。
[Ctrl] + [F5] キーを押下することでビルドと実行が行われ、Android Emulator上で動作確認ができます。コードを変更しましたが、これまでと変わらない動作であることが確認できると思います。
Flexible Sync について
Flexible Syncは、Pertitionよりも柔軟に設定が可能なデータアクセス権の設定手段です。公式サイトではPertitionよりもFlexible Syncが推奨されています。
MongoDB Cloudの [App Services] からこれまで使っていたアプリを選択し、メニューから [Device Sync] をクリックします。これまではPertitionしかありませんでしたが、Flexibleが選択できるようになっています。
Flexible Syncの設定
ここでは、Partitionと同等の設定をFlexibleで記述してみます。Flexibleを使用する場合は区分指定でのアクアス許可設定ではなくなるので、Partition名が不要になります。それに伴い、Define Permissionの書き方も変わってきます。詳しい説明はガイドを参照してください。
- 今開いているDevice Sync画面右上の [Terminate Sync] をクリックします。確認ダイアログが表示されるので、テキストボックスに “Terminate sync” と入力し、[Terminate Sync] ボタンをクリックします。
- 削除後、[Flexible] が選択できるようになるので、これをクリックします。
- Define Permissionに以下の値を入力します。
{ "defaultRoles": [ { "name": "admin-read-write", "applyWhen": { "%%user.custom_data.is_admin": true }, "read": true, "write": true }, { "name": "user-read-only", "applyWhen": {}, "read": true, "write": false } ] }
- [Enable Sync] をクリックし、確認ダイアログで [Save Changes] をクリックします。
以上で、Flexible Syncの設定は完了です。
コードの書き換えと実行
先ほどはPartitionSyncConfigurationクラスを使用してRealmオブジェクトを作成しましたが、Flexibleの場合は、FlexibleSyncConfigurationクラスを使用します。
- TopFragment.cs L61 〜 63 のコードを、下記のように変更します。Flexibleの場合はSubscriptionの登録が必要です。Subscriptionとは、デバイス同期の対象となるドキュメントをクエリで指定するもので、この例ではすべてのInventoryコレクションのドキュメントをデバイス同期の対象としています。
var config = new FlexibleSyncConfiguration(app.CurrentUser, "public.realm") { PopulateInitialSubscriptions = (realm) => { var myInventory = realm.All<Inventory>(); realm.Subscriptions.Add(myInventory); } }; using Realm publicRealm = await Realm.GetInstanceAsync(config);
- 同様に、以下のコードも下記のように変更します。
- TopFragment.cs L100 〜 103
- AddFragment.cs L54 〜 56
- EditFragment.cs L72 〜 74、L106 〜 108
using Realm publicRealm = await Realm.GetInstanceAsync( new FlexibleSyncConfiguration(app.CurrentUser, "public.realm"));
以上で、コードの書き換えは完了です(※ここまでのコードはGitLabからダウンロード可能)。
一度状態をリセットするために、まずはMongoDB Atlasに保存されているInventoryコレクションのドキュメントをすべて消去します。そして、エミュレーターで動いているアプリもアンインストールします。
その後、Visual Studioで [Ctrl] + [F5] を押下してアプリを再インストールし、起動します。Partitionと同様に操作でき、MongoDB Atlasに同期されていることを確認できます。
おわりに
今回は、Realmライブラリを更新し、Flexible Syncの動作確認を行いました。細かく比較はしていませんが、Partitionに比べてより柔軟なアクセス許可の設定を行うことができます。また、Subscriptionの概念により、データ同期対象をクエリで指定できるのもFlexibleの特徴ですが、このクエリを正しく書けないと上手く同期されず、プログラミングとしては難しくなる印象を受けました。
さて、今回で「MongoDB Realmでモバイルアプリ開発を試してみよう!」の連載は終了となります。皆さまのMongoDB Realを使用したモバイルアプリケーション開発の一助となれば幸いです。
長期にわたりご愛読いただき、ありがとうございました!
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- MongoDB Realmを利用したCRUD機能を実装しよう
- MongoDB Realmのパーティションへの理解を深めよう
- Realmアプリの機能を利用して認証機能を作ろう(後編)
- サンプルプログラムで MongoDB Realm のデータ同期を確認する
- Visual StudioでXamarin+Realmアプリの開発環境をセットアップ
- Custom User Dataを利用してユーザーに管理者属性を追加しよう
- MongoDB Atlasクラスタの作成とMongoDB Realmアプリのデプロイ
- Realmアプリの機能を利用して認証機能を作ろう
- モバイルアプリケーション開発の基礎と「MongoDB Realm」の概要
- レプリケーションの諸機能と、同期接続