9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RealmAdvent Calendar 2016

Day 4

Realm Object Serverを使って、リモートデバッグしてみる

Posted at

Androidアプリを作っていると、

  • 「いまどんな値がRealmに入ってるんだっけ?」
  • 「ここの数字を2に書き変えたらうまくいくのかな?」

みたいなデバッグをしたくなることがよくあります。
adb pull / push でRealmデータベースを抜いたり入れたりするのはめんどくさすぎるので、できればリモートデバッグがしたいですよね。

「いまどんな値がRealmに入ってるんだけ?」という要求については、 @zaki50 さんによる神拡張 stetho-realm で概ね目的は果たせるのですが、「ここの数字を2に書き換えたらうまくいくのかな?」のようなデバッグはそう簡単にはできません。

Realm Mobile Platformで実現できるか・・・?

Realm Browserを使うと、Realm Object Serverに保持されている値をさらっと書き換えたり消したりすることができます。
ということは、Realm Object Serverを介して「ここの数字を2に書き換えたらうまくいくのかな?」というデバッグをすることができるのでは? と試してみたくなりました。

サンプルアプリ

Slice 2.png

メッセンジャーライクなアプリで、内部設計的には、Messageモデルをrealm-android-adaptersのRealmBaseAdapterでそのままリストビューに表示させてるだけです。

Slice.png

ソースをちょっと変える

build.gradle

realm {
  syncEnabled = true
}

を追記します。

Applicationクラス

Realm.init(this);

のようにしていたところは、

Realm.init(this);

SyncCredentials credentials = SyncCredentials.usernamePassword(
        "yusuke.iwaki@example.com", "hogehoge", false);
SyncUser.loginAsync(credentials, "http://localhost:9080/auth", new SyncUser.Callback() {
    @Override
    public void onSuccess(SyncUser user) {
        RealmConfiguration config = new SyncConfiguration.Builder(user, "realm://localhost:9080/~/debug").build();
        Realm.setDefaultConfiguration(config);
    }

    @Override
    public void onError(ObjectServerError error) {
    }
});

このように、Realm Object Serverに接続するようなコードに変えます。

Realm Object Serverを起動する

./start-object-server.command 

これを実行すると、

Your admin access token is: ewoJImlkZW50aXR5IjogImFkbWluIi~~(略)~~9eCEinw==

みたいなのが出るので、こいつをメモ。

ユーザを適当につくる

SyncCredentials credentials = SyncCredentials.usernamePassword(
        "yusuke.iwaki@example.com", "hogehoge", false);

でログインできるように、管理画面でユーザをつくります。

image

ポートフォワーディング

アプリが http://localhost:9080/auth のソースでRealm Object Serverに接続できるようにするには

adb reverse tcp:9080 tcp:9080

で、端末の9080版ポートをMacにフォワードさせる必要があります。

アプリのソースを http://10.0.3.2:9080/auth のように、直接Realm Object Serverを向くように変えるでもOKです。

で、アプリを実行すると・・・

Slice 3.png

見た目は何も変わりません。

「あれ、古いデータが残ってるぞ?」というときは

一旦アプリを終了させてもう一度起動すると、SyncConfigurationを反映したRealm DBが見えるようになるかと思います。

Applicationクラスで非同期でSyncConfigurationをsetDefaultしているため、初回起動時はそれより先にActivityのonCreateが呼ばれ、 Realm.getDefaultInstance() で正しくSync DBが見えないのです。
もう一度起動し直すことによって、Applicationクラスは初期化されずそのまま、Activityだけが初期化されるので、正しくSync DBが見えるようになる、というわけです。

Realm BrowserでRealm Object Serverに接続

/debug で終わるデータベースが作られています。

Slice 2.png

中を覗くと、それっぽいデータが見えます。

image

さわってみる

test.gif

リモートデバッグっぽい感じで、DBをごにょごにょできました。
Realm Browser側がオートリフレッシュがかかるので、非常に便利ですね。

RealmChangeListenerとかもちゃんと発動しますね!

test.gif

サンプルアプリでは、「syncstate=0のMessageが来たら、それを1に変えて、もうしばらくしたら2に変える」という動作をするバックグラウンドサービスが動いていますが、RealmBrowserで syncstate=0にデータを書き換えた場合にもリスナーがしっかり発動してくれます。

 
ざっくり変更差分はこんな感じです。
https://github.com/YusukeIwaki/RealmDebugSample/commit/e94b3cd1ed476be50882d82b8b3d73ad92ab0624

まとめ

Realm Object Serverの本来の使い方ではありませんが、ちょっと一工夫をすることでリモートデバッグにも使えそう、ということがわかりました。

今回試したソースは、デバッグ版でもリリース版でもSyncConfigurationを使うようになってますが、たとえば

  • デバッグビルドではSyncConfigurationでリモートデバッグ可能
  • リリースビルドでは従来通りRealmConfiguration

のようにしておくと、「やべー、リモートデバッグ有効にしたままリリースしちゃった!」てきな事故にはならずに済みますねw

 
ということで、みなさんRealm Object Server使ってみましょう!

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?