「Flexible Sync」でデータを同期してみよう

2022年11月2日(水)
池田 卓司

はじめに

前回で、ひと通り機能の実装は完了しました。本連載が始まってから約1年が経過し、MongoDB Cloudのインターフェースも変わりRealmにも色々と機能が追加されています。それに応じて、Realmライブラリのバージョンも上がっています。

最終回となる今回は、前回までに実装した機能を最新のライブラリに置き換えて、再実装していきます。また、連載当初にはなかった新しい同期機能“Flexible Sync”を試してみます。

Realmライブラリの更新

2022年10月12日現在のRealmライブラリの最新バージョン「10.17.0」をインストールします。ライブラリはNuGet Galleryから確認できます。

インストール

本手順では、Visual StudioのNugetパッケージマネージャーコンソールから、最新のRealmライブラリに置き換える方法を説明します。

  1. Visual Studioでモバイルアプリのソリューションを開きます(※GitLabにてコードを公開)。
  2. メニューバーから、[ツール] - [NuGet パッケージ マネージャー] - [パッケージ マネージャー コンソール] をクリックします。

  3. パッケージマネージャーコンソールが表示されるので、以下のコマンドを入力し、現在のRealmライブラリのバージョンを確認します。
    PM> Get-Package -Filter Realm | Select-Object Id, Version
    
    Id    Version
    --    -------
    Realm 10.7.1
  4. 以下のコマンドを入力し、最新バージョンをインストールします。
    PM> Install-Package Realm -Version 10.17.0
  5. もう一度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の書き方も変わってきます。詳しい説明はガイドを参照してください。

  1. 今開いているDevice Sync画面右上の [Terminate Sync] をクリックします。確認ダイアログが表示されるので、テキストボックスに “Terminate sync” と入力し、[Terminate Sync] ボタンをクリックします。

  2. 削除後、[Flexible] が選択できるようになるので、これをクリックします。

  3. 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
        }
      ]  
    }
  4. [Enable Sync] をクリックし、確認ダイアログで [Save Changes] をクリックします。

以上で、Flexible Syncの設定は完了です。

コードの書き換えと実行

先ほどはPartitionSyncConfigurationクラスを使用してRealmオブジェクトを作成しましたが、Flexibleの場合は、FlexibleSyncConfigurationクラスを使用します。

  1. 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);
  2. 同様に、以下のコードも下記のように変更します。
    • 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を使用したモバイルアプリケーション開発の一助となれば幸いです。

長期にわたりご愛読いただき、ありがとうございました!

クリエーションライン富山事業所 所長
Javaや.net frameworkでのアプリ開発など、主にソフトウェアエンジニアとして業務に就く傍ら、ホスティングサービスのWindowsサーバー管理など、インフラ系の業務にも従事。現在は、チームマネジメントや北陸エリアでの事業拡張業務を担当。
Twitter: https://twitter.com/cl_toyama

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています