このドキュメントでは、データ取得の基本と、Firebase データの順序付けとフィルタリングの方法について説明します。
あなたが始める前に
Get Started
にガイドで説明されているように、アプリをセットアップし、データベースにアクセスできることを確認してください。
データの取得
Firebase データは、 GetValue()
への 1 回の呼び出し、またはFirebaseDatabase
参照のValueListener
へのアタッチによって取得されます。値リスナーは、データの初期状態に対して 1 回呼び出され、データが変更されるたびに再度呼び出されます。
DatabaseReference を取得する
データベースにデータを書き込むには、 DatabaseReference
のインスタンスが必要です。
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
データを 1 回読み取る
GetValue()
メソッドを使用して、特定のパスにあるコンテンツの静的スナップショットを 1 回読み取ることができます。タスクの結果には、子データを含む、その場所のすべてのデータを含むスナップショットが含まれます。データがない場合、返されるスナップショットはnull
です。
firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").GetValue();
リクエストが行われた時点で、値を読み取る前に Future が完了するのを待つ必要があります。通常、ゲームはループで実行され、他のアプリケーションよりもコールバックが少ないため、通常は完了をポーリングします。
// In the game loop that polls for the result... if (result.status() != firebase::kFutureStatusPending) { if (result.status() != firebase::kFutureStatusComplete) { LogMessage("ERROR: GetValue() returned an invalid result."); // Handle the error... } else if (result.error() != firebase::database::kErrorNone) { LogMessage("ERROR: GetValue() returned error %d: %s", result.error(), result.error_message()); // Handle the error... } else { firebase::database::DataSnapshot snapshot = result.result(); // Do something with the snapshot... } }
これは、いくつかの基本的なエラー チェックを示しています。エラー チェックの詳細については、 firebase::Futureリファレンスを参照してください。
イベントをリッスンする
データへの変更をサブスクライブするリスナーを追加できます。
ValueListener
基本クラス
折り返し電話 | 典型的な使用法 |
---|---|
OnValueChanged | パスの内容全体に対する変更を読み取り、リッスンします。 |
OnChildListener
基本クラス
OnChildAdded | アイテムのリストを取得するか、アイテムのリストへの追加をリッスンします。リストへの変更を監視するには、 OnChildChanged およびOnChildRemoved と共に使用することをお勧めします。 |
OnChildChanged | リスト内の項目への変更をリッスンします。リストへの変更を監視するには、 OnChildAdded およびOnChildRemoved と共に使用します。 |
OnChildRemoved | リストから削除される項目をリッスンします。リストへの変更を監視するには、 OnChildAdded およびOnChildChanged と共に使用します。 |
OnChildMoved | 順序付きリスト内のアイテムの順序の変更をリッスンします。 OnChildMoved コールバックは、(現在の order-by メソッドに基づいて) アイテムの順序が変更されるため、常にOnChildChanged コールバックに従います。 |
ValueListener クラス
OnValueChanged
コールバックを使用して、特定のパスにあるコンテンツへの変更をサブスクライブできます。このコールバックは、リスナーがアタッチされたときに 1 回トリガーされ、子を含むデータが変更されるたびに再度トリガーされます。コールバックには、子データを含む、その場所にあるすべてのデータを含むスナップショットが渡されます。データがない場合、返されるスナップショットはnull
です。
次の例は、データベースからリーダーボードのスコアを取得するゲームを示しています。
class LeadersValueListener : public firebase::database::ValueListener { public: void OnValueChanged( const firebase::database::DataSnapshot& snapshot) override { // Do something with the data in snapshot... } void OnCancelled(const firebase::database::Error& error_code, const char* error_message) override { LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code, error_message); } }; // Elsewhere in the code... LeadersValueListener* listener = new LeadersValueListener(); firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").AddValueListener(listener);
Future<DataSnaphot>
の結果には、イベント時にデータベース内の指定された場所にあるデータが含まれます。スナップショットでvalue()
を呼び出すと、データを表すVariant
が返されます。
この例では、読み取りがキャンセルされたかどうかを確認するために、 OnCancelled
メソッドもオーバーライドされます。たとえば、クライアントが Firebase データベースの場所から読み取る権限を持っていない場合、読み取りをキャンセルできます。 database::Error
は、エラーが発生した理由を示します。
ChildListener クラス
子イベントは、 PushChild()
UpdateChildren()
を介して更新された子などの操作からノードの子に発生する特定の操作に応答してトリガーされます。これらはそれぞれ、データベース内の特定のノードへの変更をリッスンするのに役立ちます。たとえば、以下に示すように、ゲームはこれらのメソッドを一緒に使用して、ゲーム セッションのコメント内のアクティビティを監視する場合があります。
class SessionCommentsChildListener : public firebase::database::ChildListener { public: void OnChildAdded(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnChildChanged(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnChildRemoved( const firebase::database::DataSnapshot& snapshot) override { // Do something with the data in snapshot ... } void OnChildMoved(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnCancelled(const firebase::database::Error& error_code, const char* error_message) override { LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s", error_code, error_message); } }; // elsewhere .... SessionCommentsChildListener* listener = new SessionCommentsChildListener(); firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("GameSessionComments").AddChildListener(listener);
OnChildAdded
コールバックは通常、Firebase データベース内のアイテムのリストを取得するために使用されます。 OnChildAdded
コールバックは、既存の子ごとに 1 回呼び出され、指定されたパスに新しい子が追加されるたびに再度呼び出されます。リスナーには、新しい子のデータを含むスナップショットが渡されます。
OnChildChanged
コールバックは、子ノードが変更されるたびに呼び出されます。これには、子ノードの子孫への変更が含まれます。これは通常、 OnChildAdded
およびOnChildRemoved
呼び出しと組み合わせて使用され、アイテムのリストへの変更に応答します。リスナーに渡されるスナップショットには、子の更新されたデータが含まれています。
OnChildRemoved
コールバックは、直接の子が削除されるとトリガーされます。これは通常、 OnChildAdded
およびOnChildChanged
コールバックと組み合わせて使用されます。コールバックに渡されるスナップショットには、削除された子のデータが含まれています。
OnChildMoved
コールバックは、子の並べ替えを引き起こす更新によってOnChildChanged
呼び出しが発生するたびにトリガーされます。 OrderByChild
またはOrderByValue
で並べ替えられたデータで使用されます。
データのソートとフィルタリング
Realtime Database Query
クラスを使用して、キー、値、または子の値で並べ替えられたデータを取得できます。並べ替えられた結果を特定の数の結果またはキーまたは値の範囲にフィルター処理することもできます。
データの並べ替え
並べ替えられたデータを取得するには、次のいずれかの order-by メソッドを指定して、結果の並べ替え方法を決定することから始めます。
方法 | 使用法 |
---|---|
OrderByChild() | 指定した子キーの値で結果を並べ替えます。 | OrderByKey() | 結果を子キーで並べ替えます。 |
OrderByValue() | 結果を子の値で並べ替えます。 |
一度に使用できる order-by メソッドは1 つだけです。同じクエリで order-by メソッドを複数回呼び出すと、エラーがスローされます。
次の例は、スコア順に並べられたスコア リーダーボードをサブスクライブする方法を示しています。
firebase::database::Query query = dbRef.GetReference("Leaders").OrderByChild("score"); // To get the resulting DataSnapshot either use query.GetValue() and poll the // future, or use query.AddValueListener() and register to handle the // OnValueChanged callback.
これは、 ValueListenerと組み合わせると、各エントリのスコア順に並べられたデータベース内のリーダーボードとクライアントを同期するfirebase::Query
を定義します。データを効率的に構造化する方法については、データベースの構造化 を参照してください。
OrderByChild()
メソッドの呼び出しは、結果を並べ替える子キーを指定します。この場合、結果は各子の"score"
値によってソートされます。他のデータ型の順序付けの詳細については、クエリ データの順序付け方法を参照してください。
データのフィルタリング
データをフィルター処理するには、クエリを作成するときに limit メソッドまたは range メソッドを order-by メソッドと組み合わせることができます。
方法 | 使用法 |
---|---|
LimitToFirst() | 結果の順序付きリストの先頭から返す項目の最大数を設定します。 |
LimitToLast() | 結果の順序付けられたリストの最後から返される項目の最大数を設定します。 |
StartAt() | 選択した order-by メソッドに応じて、指定されたキーまたは値以上のアイテムを返します。 |
EndAt() | 選択した order-by メソッドに応じて、指定されたキーまたは値以下の項目を返します。 |
EqualTo() | 選択した order-by メソッドに応じて、指定されたキーまたは値に等しいアイテムを返します。 |
order-by メソッドとは異なり、複数の limit または range 関数を組み合わせることができます。たとえば、 StartAt()
() メソッドとEndAt()
メソッドを組み合わせて、結果を指定した範囲の値に制限できます。
クエリに一致するものが 1 つしかない場合でも、スナップショットはリストのままです。単一のアイテムが含まれているだけです。
結果の数を制限する
LimitToFirst()
およびLimitToLast()
メソッドを使用して、特定のコールバックで同期する子の最大数を設定できます。たとえば、 LimitToFirst()
を使用して制限を 100 に設定した場合、最初は最大 100 個のOnChildAdded
コールバックしか受け取りません。 Firebase データベースに保存されているアイテムが 100 未満の場合、アイテムごとにOnChildAdded
コールバックが発生します。
項目が変更されると、クエリに入る項目のOnChildRemoved
コールバックとクエリからドロップする項目のOnChildAdded
コールバックを受け取り、合計数が 100 に留まるようにします。
たとえば、次のコードはリーダーボードからトップ スコアを返します。
firebase::database::Query query = dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1); // To get the resulting DataSnapshot either use query.GetValue() and poll the // future, or use query.AddValueListener() and register to handle the // OnValueChanged callback.
キーまたは値でフィルタ
StartAt()
、 EndAt()
、およびEqualTo()
を使用して、クエリの任意の開始点、終了点、および等価点を選択できます。これは、データのページ付けや、特定の値を持つ子を持つアイテムの検索に役立ちます。
クエリ データの順序付け方法
このセクションでは、 Query
クラスの各 order-by メソッドによってデータがどのようにソートされるかについて説明します。
OrderByChild
OrderByChild()
を使用すると、指定された子キーを含むデータは次のように並べられます。
- 指定された子キーの
null
値を持つ子が最初に来ます。 - 指定された子キーの値が
false
の子が次に来ます。複数の子の値がfalse
の場合、それらはキーによって辞書順にソートされます。 - 指定された子キーの値が
true
の子が次に来ます。複数の子の値がtrue
の場合、それらは辞書式にキーでソートされます。 - 次に、数値を持つ子が昇順でソートされます。複数の子が指定された子ノードに対して同じ数値を持つ場合、それらはキーでソートされます。
- 文字列は数値の後に続き、辞書式に昇順にソートされます。指定された子ノードに対して複数の子が同じ値を持つ場合、それらはキーによって辞書順に並べられます。
- オブジェクトは最後に来て、キーの昇順で辞書式にソートされます。
OrderByKey
OrderByKey()
を使用してデータを並べ替えると、データはキーの昇順で返されます。
- 32 ビット整数として解析できるキーを持つ子が最初に来て、昇順でソートされます。
- 次にキーとして文字列値を持つ子が来て、辞書式に昇順にソートされます。
OrderByValue
OrderByValue()
を使用すると、子はその値によって並べ替えられます。順序付け基準は、指定された子キーの値の代わりにノードの値が使用されることを除いて、 OrderByChild()
と同じです。