サーバー構築不要!スマートフォンアプリ向けの新クラウド

トップ >ドキュメント >データストア(Android):基本的な使い方

データストア(Android)

基本的な使い方

概要

このページでは、データストア機能の基本的な使い方について解説していきます。

データストアで利用可能なデータ型

データストアでは、以下の値が利用可能です。

種類 サンプル
文字列 ABC
配列 ["orange", "apple", "grape"]
数字 123
日付 2013-09-06T01:51:03.606Z
真偽値 true または false
オブジェクト {"name":"orange"} または null
緯度経度(位置情報) 33.857619,122.378986
  • null はオブジェクト型です。
  • フィールドにデータが登録されていない場合、管理画面では (undefined) と表示されます。
    なお、一度フィールドにデータを登録した後に、登録前の状態に戻すことは出来ません。
    データ未登録状態として扱いたい場合は、null を設定してください。

アプリでの実装

NCMBObjectについて

ニフクラ mobile backendのデータストア機能はNCMBObjectを通じて利用します。
NCMBObjectはスキーマレスなJSON互換のkey-value形式のオブジェクトを扱うことができます。
オブジェクトの保存先はNCMBObjectの初期化時に指定したクラスで識別されます。

オブジェクトの保存

データストアのクラス名を指定して、NCMBObjectを作成します。
指定したクラスがデータストアに存在しない場合は、新規にクラスが作成されます。

NCMBObject obj = new NCMBObject("SaveObjectTest");
obj.put("key", "value");
obj.saveInBackground(new DoneCallback() {
    @Override
    public void done(NCMBException e) {
        if (e != null) {

            //エラー発生時の処理
        } else {

            //成功時の処理
        }
    }
});

オブジェクトの取得

データストアにある内容を取得する場合は、オブジェクトの検索を実施するか
以下のようにobjectIdを指定してfetchInBackgroundメソッドを利用します。

NCMBObject obj = new NCMBObject("TestClass");
obj.setObjectId("getTestObjectId");
obj.fetchInBackground(new FetchCallback<NCMBObject>() {

    @Override
    public void done(NCMBObject object, NCMBException e) {
        if (e != null) {
            //エラー時の処理
        } else {
            //取得成功時の処理
        }
    }
});

オブジェクトの更新

保存済み(または、objectIdを持っている)のオブジェクトに新しい値をセットして
saveInBackgroundメソッドを保存時と同様に実行することでデータストアの値が更新されます。

データストアに対しての操作を設定する

NCMBObjectには値をセットするだけではなく、
データストアに対しての操作も設定することができます。
以下にいくつかのサンプルコードをあげておきます。

  • 指定フィールドのインクリメント(すでに該当フィールドに値が存在する場合にのみ更新可能)
obj.increment("incrementKey", 1);

  • 指定したフィールドに要素がユニークになるよう配列の値を追加する
obj.addUniqueToList("list", Arrays.asList("value1", "value2"));

これらのメソッドを利用したあと、オブジェクトの更新を行うまでは、
ローカルの値を取得すると設定されたクエリ結果となるJSONObjectが返却されます。

オブジェクトの削除

オブジェクトをデータストアから非同期で削除する場合は、
deleteObjectInBackgroundメソッドを利用します。

obj.deleteObjectInBackground(new DoneCallback() {
    @Override
    public void done(NCMBException e) {
        if (e != null) {
            Assert.fail("delete object method should not raise exception:");
        }
    }
});

オブジェクトの関連付け

NCMBObjectのインスタンスに、別のNCMBObjectを設定すると、
設定したNCMBObjectへのポインタ(参照)が設定されます。
ポインタ先のオブジェクトはobjectIdがセットされている(=保存済みである)必要があります。

NCMBObject pointerObj = new NCMBObject("pointerClass");
pointerObj.setObjectId("testObjectId");

//pointerObjへのポインタをpointerフィールドに設定する
obj.put("pointer", pointerObj);

リレーション

ポインタは1つのオブジェクトへの参照しか持つことができませんが、
リレーションを利用することで、特定クラスの複数オブジェクトと関連づけることが可能です。

リレーションを追加・削除する場合は、NCMBRelationクラスを利用します。

NCMBObject childObj = new NCMBObject("ChildClass");
childObj.setObjectId("testObjectId");

NCMBObject obj = new NCMBObject("Test");

//リレーションへの追加を設定する
obj.put("relation", NCMBRelation.addRelation(Arrays.asList(childObj)));

基本的な検索の利用

データ検索にはNCMBQueryクラスを利用します。
※limitを指定していない場合、検索結果として取得される最大データ件数は100件です。
検索結果のデータ件数が多い場合は、limitとskipを活用してください。
詳細はクエリのオペレータを利用するをご覧ください。

//TestClassを検索するためのNCMBQueryインスタンスを作成
NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");

//keyというフィールドがvalueとなっているデータを検索する条件を設定
query.whereEqualTo("key", "value");

//データストアからデータを検索
query.findInBackground(new FindCallback<NCMBObject>() {
    @Override
    public void done(List<NCMBObject> results, NCMBException e) {
        if (e != null) {

            //検索失敗時の処理
        } else {

            //検索成功時の処理
        }
    }
});

標準クラスを検索する場合のクラス名

会員やロール・ファイルなど、mobile backendに標準で存在するクラスに対して、
inQueryを用いた検索など、クラス名を指定する必要がある場合は以下をご覧ください。

クラス名 役割
user 会員管理のクラス
role ロールのクラス
file ファイルストアのクラス
installation 端末情報一覧のクラス
push プッシュ通知のクラス

各クラスのデータをより効率的に検索するにはこちらをご参考ください。

検索条件を設定する

上記で使用したwhereKey:equalToメソッド以外にも、
いろいろな検索条件を設定することができます。
詳細はSDKリファレンスのNCMBQueryをご覧ください。

  • 配列に対するクエリ
NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");

//keyというフィールドに格納されている配列のうち、指定した配列データを含むものを検索する
query.whereContainedInArray("key", Arrays.asList("value1", "value2"));

  • ポインタに対する条件の設定
//SubClassを検索するクエリを作成
NCMBQuery<NCMBObject> subQuery = new NCMBQuery<>("SubClass");

//keyがvalueと一致するデータを検索
subQuery.whereEqualTo("key", "value");

//TestClassを検索するクエリを作成
NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");

//subQueryの条件と一致するデータをsubKeyフィールドで参照しているデータが検索される
query.whereMatchesQuery("subKey", subQuery);

  • リレーション先を検索する条件の設定
    • リレーション先を検索する際は通常の検索時の挙動と異なる点があります。必ず開発ガイドラインの「リレーションについて」をご確認ください。
NCMBObject pointerObj = new NCMBObject("pointerClass");
pointerObj.setObjectId("testObjectId");

//リレーションを設定
NCMBObject parentObj = new NCMBObject("TestClass");
parentObj.put("relation", NCMBRelation.addRelation(Arrays.asList(pointerObj)));
parentObj.save();

//リレーション先のクラスを検索するNCMBQueryを作成
NCMBQuery<NCMBObject> subQuery = new NCMBQuery<>("SubClass");

//parentObjのrelationフィールドにリレーションとして設定されているオブジェクトを検索する
subQuery.whereRelatedTo(parentObj, "relation");

クエリの合成

条件を複数指定することで、AND検索を行うことができます。

//keyの値が0以上かつ、10以下のデータを検索する
NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");
query.whereGreaterThan("key", 0);
query.whereLessThan("key", 10);

また、orメソッドを利用することで、複数のクエリをOR合成することができます。

NCMBQuery<NCMBObject> queryA = new NCMBQuery<>("TestClass");
queryA.whereEqualTo("keyA", "valueA");

NCMBQuery<NCMBObject> queryB = new NCMBQuery<>("TestClass");
queryB.whereEqualTo("keyB", "valueB");

NCMBQuery orQuery = new NCMBQuery<>("TestClass");
orQuery.or(Arrays.asList(queryA, queryB));

クエリのオペレータを利用する

limitやskipを指定して、検索結果の取得件数を設定することができます。
※limitを指定していない場合は、limitはデフォルトである100として検索が行われます。(REST API リファレンス:クエリの指定方法 参照)
limitの値については、必ず適切な値を設定してください。詳細はこちらをご覧ください。

NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");
query.whereEqualTo("key", "value");
query.setLimit(50);
query.setSkip(3);

List<NCMBObject> result = query.find();

指定した検索条件に一致するデータが何件あるのかを取得することができます。

NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");

query.whereEqualTo("key", "value");
int result = query.count();

検索結果のソート条件を設定することができます。
以下の例ではascendingKeyの昇順かつ、descendingKeyの降順でデータが取得されます。

NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");

query.whereEqualTo("key", "value");

//データを昇順で取得するためのフィールドを設定
query.addOrderByAscending("ascendingKey");

//データを降順で取得するためのフィールドを設定
query.addOrderByDescending("descendingKey");

List<NCMBObject> result = query.find();

includeKeyを指定すると、ポインタ先のオブジェクトを含めたデータを取得できます。

NCMBQuery<NCMBObject> query = new NCMBQuery<>("TestClass");

//postフィールドのポインタ先オブジェクトと、
//そのポインタ先オブジェクト内のauthorフィールドにあるポインタ先オブジェクトを含めて取得する
query.setIncludeKey("post.author");
List<NCMBObject> result = query.find();

//postフィールドのポインタ先オブジェクトをNCMBObjectのインスタンスとして取得
NCMBObject post = result.get(0).getIncludeObject("post");

//authorフィールドのポインタ先オブジェクトをNCMBUserのインスタンスとして取得
NCMBUser author = post.getIncludeObject("author");

上記の処理は、以下のようなJSONデータが返ってきた場合に
postとauthorにポインタ先オブジェクトの値を設定しています。

{
  "results":[
    {
      "post":{
        "author":{
          "objectId":"epaKcaYZqsREdSMY",
          "userName":"testUser",
          "authData":null,
          "mailAddress":null,
          "mailAddressConfirm":null,
          "createDate":"2013-08-28T11:27:16.446Z",
          "updateDate":"2013-08-28T12:03:28.926Z",
          "acl":{
            "*":{
              "read":true,
              "write":true
            }
          },
          "__type":"Object",
          "className":"user"
        },
        "createDate":"2013-04-11T08:52:40.587Z",
        "updateDate":"2013-04-30T07:27:05.237Z",
        "objectId":"iawe8tnglkasnaki",
        "__type":"Object",
        "className":"Post"
      },
      "createDate":"2013-04-10T10:07:48.948Z",
      "updateDate":"2013-04-30T07:21:58.482Z",
      "objectId":"rute8tnglkaritqi"
    }
  ]
}

キャッシュ

version2でのキャッシュ機能は次期アップデートで対応予定です。

管理画面での操作

クラスを新たに作成する

管理画面左側メニューのデータストアをクリックしてください。

緑の「+作成」ボタンをクリックして、新規作成を選択します。
すると以下のようなポップアップが表示されます。

クラス名を入力し、「作成する」ボタンをクリックすると、クラスが新規に作成されます。
データストアでも作成したクラスが表示されます。以下の例では作成したClass_Testが表示されています。

ファイルからクラスをインポートする

データストアでは、エクスポートしたデータや、お客様がカスタマイズしたJSON形式・テキスト形式(.txt)・CSV形式のファイルをインポートすることにより、クラスを作成することが可能です。

  • JSON形式

    JSON形式のデータをインポートする場合、インポートしたいデータは以下の例のように「results」をキーとする配列に格納されている必要があります。
{
  "results":[
    {
      "name":"Cola",
      "color":"black"
    },
    {
      "name":"Coffee",
      "color":"black"
    },
    {
      "name":"Dr Pepper",
      "color":"black"
    },
    {
      "name":"Milk",
      "color":"white"
    }
  ]
}

型ごとに問題

{
    "results": [
        {
            "acl": {
                "*": {
                    "read": true,
                    "write": true
                }
            },
            "createDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:42:52.468Z"
            },
            "updateDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:42:52.485Z"
            },
            "dataField": "文字列",
            "objectId": "GMLduZNSVuPGv6ND"
        },
        {
            "acl": {
                "*": {
                    "read": true,
                    "write": true
                }
            },
            "createDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:06.498Z"
            },
            "updateDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:06.499Z"
            },
            "dataField": 123,
            "objectId": "A7NHPMMtO66Az2bW"
        },
        {
            "acl": {
                "*": {
                    "read": true,
                    "write": true
                }
            },
            "createDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:22.087Z"
            },
            "updateDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:22.088Z"
            },
            "dataField": [
                "orange",
                "apple",
                "grape"
            ],
            "objectId": "AXyHdmYIlkJPE8WO"
        },
        {
            "acl": {
                "*": {
                    "read": true,
                    "write": true
                }
            },
            "createDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:43.604Z"
            },
            "updateDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:43.622Z"
            },
            "dataField": {
                "__type": "Date",
                "iso": "2013-09-06T01:51:03.606Z"
            },
            "objectId": "qe5DlJHK6fjjd2KP"
        },
        {
            "acl": {
                "*": {
                    "read": true,
                    "write": true
                }
            },
            "createDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:52.078Z"
            },
            "updateDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:43:52.078Z"
            },
            "dataField": true,
            "objectId": "ArWIX0u5a94kHIt3"
        },
        {
            "acl": {
                "*": {
                    "read": true,
                    "write": true
                }
            },
            "createDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:44:23.616Z"
            },
            "updateDate": {
                "__type": "Date",
                "iso": "2021-05-11T09:44:23.617Z"
            },
            "dataField": {
                "name": "orange"
            },
            "objectId": "u04j2r6JDVpx6FEc"
        }
    ]
}
  • テキスト形式(.txt)・CSV形式

    また、テキスト形式やCSV形式のファイルからインポートした場合、1行目がフィールド名として認識され、2行目以降の内容がデータとしてインポートされます。
    以下の例では、name、flag、numberというフィールドが作成され、2行目以降がデータとして登録されます。
    ダブルクォーテーションで囲った文字は、文字列として認識されます。それ以外の記述方法は、データストアで利用可能な型に準じています。
    • 注意
      • カンマの直後に半角スペースを入れると正しく値が認識されない場合があります
      • オブジェクト形式(緯度経度、日付型、ポインタ型 等)はインポートできません
name,flag,number
"hoge",true,123
"fuga",true,10

ファイル形式の種類に関係なく、インポートするファイルは、日本語の文字化けを防ぐために、文字コードをUTF-8にして保存してください。また、UTF-8のファイルでもBOMがついているファイルをインポートしようとすると、エラーが返却されますので注意してください。
インポート可能な最大ファイルサイズは2GBとなっています。

インポートしたい場合は、データストアの画面にて、緑の「+作成」ボタンをクリックしてインポートを選択します。

以下のようなポップアップが表示されますので、クラス名を入力し、インポートするファイルを選択して、「インポート」ボタンをクリックしてください。

エクスポートしたデータをインポートするなど、すでに同じ名前のクラスがデータストア内に存在している場合、重複エラーが発生します。
その場合は、既存のクラスを削除してからもう一度インポートしてください。

データをエクスポートしたい場合には以下のページをご覧ください。
エクスポート機能を利用する

クラスを削除する

上で作成したClass_Testをクラスを削除するには、データストアの右上にある「クラスの編集」ボタンをクリックします。

以下のページに遷移するので、「クラスの削除」ボタンをクリックします。

右上にある「クラスの削除」ボタンをクリックすると、以下のポップアップが表示されます。

クラスを削除していいか確認してから、クラスの削除を実行してください。

フィールドを新たに作成する

データストアの画面で、フィールドを作成するクラスをクリックしてください。

データストアの上側にある「+新しいフィールド」ボタンをクリックします。

フィールド名を入力して、「作成する」ボタンをクリックしてください。

フィールドを削除する

フィールドの削除は、クラスの編集画面から行います。データストアの右上にある「クラスの編集」ボタンをクリックしてください。

作成したフィールドの左側にチェックボックスがあります。削除するフィールドのチェックボックスをクリックし、「+新規フィールド」ボタンの横にある削除ボタンをクリックすると、ポップアップが表示されます。

フィールドを削除していいか確認してから、フィールドの削除を実行してください。

レコードを追加する

データストアの画面で、レコードを追加するクラスをクリックしてください。

データストアの左上にある「+新しいレコード」をクリックすると、空のレコードが表示されます。
また、レコードが1つも存在しないクラスの場合、データストアの中央にも、レコード追加のボタンが表示されます。

データストアでは、追加したフィールドのみ編集可能で、その他のフィールドは自動的に値が格納されます。
以下の例では、nameというフィールドを追加したので、空のレコードをダブルクリックし、nameフィールドに「tarou」と入力しました。
エンターキーを押すと値が登録され、objectIdやcreateDateなどが自動的に登録されます。
レコードの追加
値を編集中の時は、データ型を選択する吹き出しが表示されるので、文字列や数値など、どのデータ型で値を登録するのか設定することができます。
データ型の選択

レコードを削除する

各レコードの左側にあるチェックボックスをクリックし、「+新しいフィールド」ボタンの横にある「削除」ボタンをクリックすると、ポップアップが表示されます。

レコードを削除していいか確認してから、レコードの削除を実行してください。

レコードの検索

データストアにあるデータが増えてきた場合などに、絞り込み検索を使って効率的にデータストアを閲覧することが可能です。
データストアの左下にある、「絞り込み」ボタンをクリックすると、検索条件を設定することができます。
絞り込み検索1
絞り込み検索の条件は、以下のように設定します。

  • フィールド名を指定する
  • 検索する値を入力する
  • 検索する値のデータ型を指定する
  • 検索条件を指定する
  • 適用ボタンをクリック

この時、検索条件で「いずれかと同じ」「いずれかを含む」「いずれとも違う」を選択した場合は、配列形式で異なったデータ型の値を検索条件に指定することが可能です。
以下の例では、numberというフィールドで、数値として登録された「1」と、文字列として登録された「1」を検索条件で指定しています。
絞り込み検索3
また、検索条件追加のアイコンをクリックすることで、検索条件を複数設定できます。

※ null(オブジェクト)のデータを検索した場合、データ未登録の(=管理画面上で(undefined)と表示されている)データも検索されます。
※「リレーションを見る」をクリックし遷移した画面にて検索を行う場合は、開発ガイドラインの「リレーションについて」をご確認ください。

クラスのパーミッションを設定する

クラスの編集画面で、右上の「パーミッションの設定」ボタンをクリックします。
クラスのパーミッション設定
ポップアップが表示されるので、「+新しいパーミッション」をクリックしてパーミッションの設定を追加してください。
対象を会員やロールに限定することで、パーミッションを一部の会員に限定することが可能です。

クラスのパーミッションを削除する

クラスのパーミッションは、各行の左側にあるチェックボックスをクリックし、削除ボタンをクリックすると削除できます。

レコードのパーミッションを設定する

レコードのパーミッションを設定するには各レコードの右側にあるパーミッション編集ボタンをクリックします。
レコードのパーミッション設定画面
パーミッション設定画面が表示されますので、「+新しいパーミッション」ボタンをクリックして、パーミッションを設定してください。

レコードのパーミッションを削除する

レコードのパーミッションは、各行の左側にあるチェックボックスをクリックし、削除ボタンをクリックすると削除できます。

暗号化の設定

mobile backendへのデータ保存時に、暗号化を実施するかフィールドごとに設定することが可能です。
※暗号化処理に関する詳細情報については、開発ガイドライン:内部データベースについてをご参照ください。
各データ型の暗号化可否については以下の通りです。

種類 暗号化可否 備考
文字列
配列 各要素のデータ型の暗号可否に従う
数字 暗号化されずに保存されます
日付 暗号化されずに保存されます
真偽値 暗号化されずに保存されます
オブジェクト { key : value } のvalueのみ、各データ型の暗号可否に従って暗号化されます
緯度経度 暗号化されずに保存されます

管理画面での暗号化設定方法

データストアを開き、クラスを選択して右上の「クラスの編集」ボタンをクリックしてください。

フィールドの一覧が表示され、暗号化が可能なフィールドのみ「暗号化する」ボタンがクリックできるようになっています。

※なお、暗号化が可能であっても既にデータが存在しているフィールドについては、値を持つレコードを削除していただかないと、暗号化への切り替えはできません。ご注意ください。

「暗号化する」ボタンをクリックすると以下のような確認画面が表示されますので、問題なければ暗号化してください。

暗号化を解除する場合は、クラスの編集画面にて「暗号化を解除する」ボタンをクリックしてください。

※会員クラスのpasswordフィールドについては、暗号化有無にかかわらず管理画面上では表示されません。
※一度暗号化したフィールドは、クラス内該当フィールドのデータが全て削除されない限り、暗号化の設定を解除することはできません。
※暗号化したフィールドでは、下記記載のオペレータが利用不可となります。

  • 項目の検索
機能 オペレータ
より小さい $lt
より大きい $gt
以下 $lte
以上 $gte
正規表現での比較 ※文字列のみ $regex
  • 複合条件検索
機能 オペレータ
サブクエリと合致するデータのうち、クエリとサブクエリで指定したキーの値が一致するデータを取得 $select
  • ポインタの検索(リレーションも含む)
機能 オペレータ
等しい(1項目) なし
サブクエリに合致するデータを、ポインタとして持っているデータを取得 $inQuery
オブジェクトIDが指定された親のリレーションにひもづく子のデータを取得 $relatedTo
  • 位置情報検索
機能 オペレータ
指定位置から距離が近い順でデータを取得
(orderを指定した場合は、orderが優先される)
オプションで最遠距離を以下の単位で指定可能
$maxDistanceInMiles → マイル
$maxDistanceInKilometers → キロメートル
$maxDistanceInRadians → ラジアン
$nearSphere
指定矩形の内側に存在するデータを取得
矩形は$boxを使って左下、右上を指定
$within / $box
  • その他クエリのキーについて
機能 キーの名前
並び順を指定する
(降順はマイナス付与)
カンマで区切ると複数項目の並べ替えが可能
order

お探しの内容が見つからなかった場合はユーザーコミュニティ もご活用ください。(回答保証はいたしかねます)
なお、 Expertプラン以上のお客様はテクニカルサポートにてご質問を承らせて頂きます。

推奨画面サイズ1024×768px以上

ページの先頭へ