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

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

データストア(Kotlin)

基本的な使い方

概要

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

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

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

種類 サンプル
文字列 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を作成します。
指定したクラスがデータストアに存在しない場合は、新規にクラスが作成されます。

import com.nifcloud.mbaas.core.NCMB
import com.nifcloud.mbaas.core.NCMBException
import com.nifcloud.mbaas.core.NCMBObject
import com.nifcloud.mbaas.core.NCMBCallback

<省略>

// SaveObjectTestのNCMBObjectを作成
val obj = NCMBObject("SaveObjectTest")
// オブジェクトに値を設定
obj.put("keyString", "value") //文字列
obj.put("keyInt", 123) //数値

val testArray = JSONArray()
testArray.put("testString1")
testArray.put("testString2")
obj.put("keyArray", testArray) //配列

obj.put("keyBoolean",true) //真偽値

val now = Date()
obj.put("keyDate", now) //日付

val testObject = JSONObject()
testObject.put("objKey", "objValue")
obj.put("keyObject", testObject) //オブジェクト
// データストアへの登録を実施
obj.saveInBackground(NCMBCallback { e, ncmbObj ->
    if (e != null) {
        //エラー発生時の処理
    } else {
        //成功時の処理
    }
})

  • 注意: オブジェクトに値を設定する場合、"キー", "値" を指定する必要があります。キー名にはcreateDate, updateDate, objectIdを設定することができないので、ご注意ください。
オブジェクトの取得

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

取得したオブジェクトのフィールドに登録されているデータを取得する場合、

型に合わせて以下のように各種getメソッドが使用できます。

データ型 getメソッド 返り値の型(kotlin)
文字列 getString String
配列 getArray JSONArray
数字 getInt, getDouble Int, Double
日付 getDate Date
真偽値 getBoolean Boolean
オブジェクト getJson JSONObject
緯度経度(位置情報) getGeo NCMBGeopoint
  • 注意:
    objectId, createDate, updateDateは規定のフィールドです。それぞれgetObjectId, getCreateDate, getUpdateDateという取得するための専用メソッドが用意されています。

以下はgetStringの使用例です。

// TestClassへのNCMBObjectを設定
val obj = NCMBObject("TestClass")
obj.put("player", "Taro") //文字列
// objectIdプロパティを設定
obj.setObjectId("getTestObjectId")
// データストアの取得を実施
obj.fetchInBackground(NCMBCallback { e, ncmbObj ->
    if (e != null) {
        //エラー時の処理
    } else {
        //取得成功時の処理
        //第一引数にフィールド名を指定
        println(obj.getString("player"))
        // -> Taro

        // 必要な場合は第二引数にデフォルトの返り値を指定
        println(obj.getString("name", "一致するフィールド名が存在しません"))       
        // -> 一致するフィールド名が存在しません

        //デフォルト値の指定がない場合
        println(obj.getString("name"))
                // -> null
    }
})

以下はgetIntの使用例です。

// TestClassへのNCMBObjectを設定
val obj = NCMBObject("TestClass")
obj.put("score", 10) //数字
// objectIdプロパティを設定
obj.setObjectId("getTestObjectId")
// データストアの取得を実施
obj.fetchInBackground(NCMBCallback { e, ncmbObj ->
        if (e != null) {
                //エラー時の処理
        } else {
                //取得成功時の処理
                //第一引数にフィールド名を指定
                println(obj.getInt("score"))
                // -> 10

                // 必要な場合は第二引数にデフォルトの返り値を指定
                println(obj.getInt("number", 0))
                // -> 0

        //デフォルト値の指定がない場合
        println(obj.getInt("number"))
                // -> null
        }
})

オブジェクトの更新

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

// TestClassへのNCMBObjectを設定
val obj = NCMBObject("TestClass")
// objectIdプロパティを設定
obj.setObjectId("getTestObjectId")    
// オブジェクトに値を設定
obj.put("fieldA", "Hello, NCMB!!")
obj.put("fieldB", 30)
// データストアへの更新を実施
obj.saveInBackground(NCMBCallback { e, ncmbObj ->
    if (e != null) {
        //更新に失敗した場合の処理
        Log.d("error","更新に失敗しました : " + e.message)
    } else {
        //更新に成功した場合の処理
        val result = ncmbObj as NCMBObject
        Log.d("success","更新に成功しました ObjectID : " + result.getObjectId())
    }
})

オブジェクトの削除

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

// TestClassへのNCMBObjectを設定
var obj = NCMBObject("TestClass")
// objectIdプロパティを設定
obj.setObjectId("Mz6xym6wNi63lxb8")
// データストアから削除
obj.deleteInBackground(NCMBCallback { e, ncmbObj ->
        if (e != null) {
            //保存に失敗した場合の処理
            Log.d("failure", "削除に失敗しました : " + e.message)
        }
        else {
            Log.d("success", "削除に成功しました")
        }
})

基本的な検索の利用

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

import com.nifcloud.mbaas.core.NCMBQuery
<省略>

//TestClassを検索するためのNCMBQueryインスタンスを作成
val query = NCMBQuery.forObject("TestClass")

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

//データストアからデータを検索
query.findInBackground (NCMBCallback { e, objects ->
        if (e != null) {
                //エラー時の処理
                println( "検索に失敗しました。エラー:" + e.message)
        } else {
                //成功時の処理
                println("検索に成功しました。")
                if(objects is List<*>) {
                        for (obj:Any? in objects) {
                                if (obj is NCMBObject) {
                                        println(obj.getObjectId())
                                }
                        }
                }
        }
})

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

会員、端末情報、プッシュ通知など、mobile backendに標準で存在するクラスに対して検索する場合、以下のように書くことで検索が可能です。

val queryUser = NCMBQuery.forUser()
val queryInstallation = NCMBQuery.forInstallation()
val queryPush = NCMBQuery.forPush()

  • ※注意

会員管理にて表示される会員データに関しては、デフォルトでは【会員自身にのみ】、読み込み・書き込み権限が付与されております。権限が付与されている場合は、権限を持っている会員でログインした状態でのみ、データにアクセスすることが可能です。
参考: アクセス権限設定をご確認ください。

検索条件を設定する

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

  • 配列に対するクエリ
val query = NCMBQuery.forObject("TestClass")

//keyというフィールドに格納されている配列のうち、指定した配列データを含むものを検索する
val objs = setOf<Int>(1,2,3)
query.whereContainedInArray("keyArray", objs)

クエリの合成

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

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

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

val query1 = NCMBQuery.forObject("TestClass")
query1.whereLessThan("keyInt", 100)
val query2 = NCMBQuery.forObject("TestClass")
query2.whereGreaterThan("keyInt", 0)
val queries: List<NCMBQuery<NCMBObject>> = listOf(query1, query2)
val query = NCMBQuery.forObject("TestClass")
query.or(queries)
query.findInBackground (NCMBCallback { e, objects ->
        if (e != null) {
                //エラー時の処理
                println( "検索に失敗しました。エラー:" + e.message)
        } else {
                //成功時の処理
                println("検索に成功しました。")
        }
})

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

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

val query = NCMBQuery.forObject("TestClass")

query.whereEqualTo("key", "value")
query.limit = 20
query.skip = 10

val objects = query.find()

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

val query = NCMBQuery.forObject("TestClass")

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

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

val query = NCMBQuery.forObject("TestClass")

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

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

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

val result = query.find()

管理画面での操作

クラスを新たに作成する

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

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

クラス名を入力し、「作成する」ボタンをクリックすると、クラスが新規に作成されます。
データストアでも作成したクラスが表示されます。以下の例では作成した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以上

ページの先頭へ