FJCT_ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

Parse Serverのデータストア操作法(Android SDK編)

NCMBのクロージングに伴って、アプリのバックエンド移行先を検討する必要が出ています。その開発については申し訳ない限りなのですが、そのために必要な情報は適宜お届けしていきます。

この記事では、移行先の候補であるParse Serverについて、その基本的な使い方を解説します。今回はAndroid SDKです。

インストール

build.gradle (モジュールではなく)に以下を追記します。

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

プロジェクトの build.gradle に以下を追記します。現在の最新バージョンは4.2.1です。

dependencies {
    implementation "com.github.parse-community.Parse-SDK-Android:parse:4.2.1"
}

初期化

まずSDKをインポートします。

import com.parse.Parse;

そして onCreate にて初期化します。

import android.app.Application;

public class App extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    Parse.initialize(new Parse.Configuration.Builder(this)
      .applicationId("YOUR_APP_ID")
      // if defined
      .clientKey("YOUR_CLIENT_KEY")
      .server("http://localhost:1337/parse/")
      .build()
    );
  }
}

データストアの使い方

オブジェクトの作成

まず基本形です。NCMBでいう NCMBObject obj = new NCMBObject("GameScore"); に相当する処理です。

ParseObject gameScore = new ParseObject("GameScore");

新規作成

フィールドの追加は put メソッドで行います。

gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.saveInBackground();

更新

更新は新規保存と同じく saveInBackground メソッドで行います。

gameScore.put("score", 1338);
gameScore.put("cheatMode", true);
gameScore.saveInBackground();

特殊な更新操作

以下のメソッドはNCMBと同じように使えるメソッドです。

メソッド名 説明
increment 数値のインクリメント
add データの配列による追加
addAll データの配列による追加(引数が配列版)
addUnique データが配列に対してユニークな場合に追加
addAllUnique データが配列に対してユニークな場合に追加(引数が配列版)
removeAll 該当する値を配列から削除

フィールドを消す

フィールドの値を削除する際には remove を行ったあと、保存します。

gameScore.remove("playerName");
gameScore.saveInBackground();

削除

データの削除は deleteInBackground メソッドで行います。

gameScore.deleteInBackground();

値の取得

各フィールドの値を取得する際には get メソッドを使います。

gameScore.get("score");
// 1338

他にも型によって getStringgetBooleangetInt メソッドなどが用意されています。

規定のフィールドは以下の通りです。

String objectId = gameScore.getObjectId();
Date updatedAt = gameScore.getUpdatedAt();
Date createdAt = gameScore.getCreatedAt();
ParseACL acl = gameScore.getACL();

検索

クエリーオブジェクトの作成

データを検索する際には、 ParseQuery.getQuery を使います。

ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");

データ1件の取得

データを1件だけ取得する場合には、objectIdを指定します。

query.getInBackground("xWMyZ4YEGZ", new GetCallback<ParseObject>() {
  public void done(ParseObject object, ParseException e) {
    if (e == null) {
      // 取得できた場合
    } else {
      // エラーが発生した場合
    }
  }
});

既存データの再取得を行う場合には fetchInBackground メソッドを使います。

obj.fetchInBackground(new GetCallback<ParseObject>() {
  public void done(ParseObject object, ParseException e) {
    if (e == null) {
      // 取得できた場合
    } else {
      // エラーが発生した場合
    }
  }
});

条件を指定して検索

データを検索する際には、条件を指定して findInBackground メソッドで取得します。

query.whereEqualTo("playerName", "Dan Stemkoski");
const results = await query.findInBackground();
query.findInBackground(new FindCallback<ParseObject>() {
    public void done(List<ParseObject> scoreList, ParseException e) {
        if (e == null) {
            Log.d("score", "Retrieved " + scoreList.size() + " scores");
        } else {
            Log.d("score", "Error: " + e.getMessage());
        }
    }
});

最初の一件を取得する婆には getFirst または getFirstInBackground メソッドを使います。配列ではなく、Parse.Objectが返ってきます(またはnull)。

query.getFirstInBackground(new GetCallback<ParseObject>() {
  public void done(ParseObject object, ParseException e) {
    if (object == null) {
      Log.d("score", "The getFirst request failed.");
    } else {
      Log.d("score", "Retrieved the object.");
    }
  }
});

結果の行数も欲しい場合には countInBackground を使います。この場合、結果のカウント数のみが返ってきます。

query.countInBackground(new CountCallback() {
  public void done(int count, ParseException e) {
    if (e == null) {
      // The count request succeeded. Log the count
      Log.d("score", "Sean has played " + count + " games");
    } else {
      // The request failed
    }
  }
});

なお、検索条件はNCMBとほぼ同じように指定できます。

  • whereEqualTo
  • whereNotEqualTo
  • whereGreaterThan
  • whereGreaterThanOrEqualTo
  • whereLessThan
  • whereLessThanOrEqualTo
  • whereContainsAll
  • whereContainedIn
  • whereNotContainedIn
  • whereExists
  • whereDoesNotExist
  • whereStartsWith
  • whereFullText

また、クエリーの結果を検索条件に指定する whereMatchesKeyInQuerywhereDoesNotMatchKeyInQuery もあります。

ParseQuery<ParseObject> teamQuery = ParseQuery.getQuery("Team");
teamQuery.whereGreaterThan("winPct", 0.5);
ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
userQuery.whereMatchesKeyInQuery("hometown", "city", teamQuery);
userQuery.findInBackground(new FindCallback<ParseUser>() {
  void done(List<ParseUser> results, ParseException e) {
        // 結果
  }
});

その他、結果の絞り込みを行うメソッドです。

  • setLimit
  • setSkip
  • orderByAscending
  • orderByDescending
  • addAscendingOrder
  • addDescendingOrder

ポインター

ParseObject同士をつなげるポインター機能です。NCMBでも同様の機能がありますが、よりパワーアップした使い方ができます。

これはGemeオブジェクトに対して、現在のユーザーを紐付けた例です。

ParseObject game = new ParseObject("Game");
game.put("createdBy", ParseUser.getCurrentUser());

ポインターになるオブジェクトは複数指定できます。

ParseObject scimitar = ...
ParseObject plasmaRifle = ...
ParseObject grenade = ...
ParseObject bunnyRabbit = ...

ArrayList<ParseObject> weapons = new ArrayList<ParseObject>();
weapons.add(scimitar);
weapons.add(plasmaRifle);
weapons.add(grenade);
weapons.add(bunnyRabbit);

ParseUser.getCurrentUser().put("weaponsList", weapons);

どちらも get メソッドでデータを取得できます。

ArrayList<ParseObject> weapons = ParseUser.getCurrentUser().get("weaponsList");

データ取得時にポインターデータも取得する場合には include メソッドを使います。

ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
userQuery.include("weaponsList");
userQuery.findInBackground(new FindCallback<ParseUser>() {
  public void done(List<ParseUser> userList, ParseException e) {
  }
});

ローカルへのデータ保存

ネットワークがつながっていない場合など、ローカルにデータを保存できます。

ParseObject gameScore = new ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.pinInBackground();

ローカルデータを取得する場合には、 fromLocalDatastore を実行しておきます。

ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");
query.fromLocalDatastore();
query.getInBackground("xWMyZ4YEGZ", new GetCallback<ParseObject>() {
  public void done(ParseObject object, ParseException e) {
    if (e == null) {
      // object will be your game score
    } else {
      // something went wrong
    }
  }
});

注意点

Parse Server向けのKotlin SDKはないようです。そのため、Kotlin環境下で使う場合にも、Java製のSDKを利用する方法になるようです。

まとめ

Parse Serverのデータストア操作はNCMBとほぼ変わりません。ただし、スキーマレスではないので、管理画面であらかじめスキーマ設計を行う必要がある点に注意してください。Parse.Schemaという仕組みを使うことでNode.jsからスキーマ生成もできますが、あまり頻度が多くはないので管理画面で作る方が手軽でしょう。

サービス終了に伴って開発が発生してしまう点については、弁解の余地がありません。開発者の皆さんに対して申し訳なく思っております。そうした中、Parse ServerはNCMBと設計思想が似ているので、移行にかかる工数が大きくなりすぎないのが利点です。

NCMBとしては今後、移行に伴う情報を積極的に発信していきます。皆さんには大変ご迷惑をおかけしますが、移行のご検討をお願い申し上げます。

Parse Platform