C#でFirebaseを使ってみよう!(4) Databaseの便利な機能を使ってみよう

あすかです。

前回は、データベースへのデータの追加・取得でファイヤー!しました。

kmycode.hatenablog.jp

今回は、さらにデータベースについてちょっとだけ掘り下げます。

絞り込み(Querying)

SQLを使うMySQLとかのデータベースでは、SELECTのときにWHEREを使いますよね。
WHERE使わず、SELECTでデータ全部持ってきてプログラムの方で絞り込むこともできるのに、です。
やっぱり大量のデータを転送するのには時間かかりますから、転送に時間かけるくらいならデータベースの方で絞り込んちゃおうという感じです。

こんなこと、ファイヤー!でできるんでしょうか?できるんです。



準備

まず準備します。

Firebaseからデータを取ってきてリスト表示するメソッドを作っておきます。

this.DatabaseDatasの型はObservableCollection<string>になってます。

あとはこれを、MVVMを使ってWPFの画面にバインドしておきます。

それから、PutAsyncを使って、データベースにデータをいくつか作っておきます。

f:id:kmynews:20170226113433p:plain

こんなデータができました。

さて、この画面、「リストをダウンロード」ボタンをクリックすると、先のDownloadTextListFromDatabaseAsyncメソッドが実行される仕組みになっています。

f:id:kmynews:20170226105744p:plain

リストをダウンロードしてみると、

f:id:kmynews:20170226113524p:plain

6件全部表示されました。

並べ替え

Queryは、OnceAsyncを実行する前にやります。
つまり、さっきのソースでこうなっている行がありましたよね。

これを、こうします。

実行する前に、FirebaseのDatabaseのルールも変更する必要があります。
FirebaseコンソールのRealtime Databaseで、「ルール」というタブがありますので、これをクリックします。

f:id:kmynews:20170226113745p:plain

そして、エディタが出てきたら、中身を以下の通りにします。

ruleの下に、sample、pathのブロックが追加され、.indexOnのところにValueが設定されています。
このValueというのは、ご想像のとおり、データベースのこの部分です。

f:id:kmynews:20170226114006p:plain

(ちょっと話がそれますが、配列(["Value", "OtherValue"])にすることで、複数の値を同時に並べ替え対象にすることが可能です)
それでは、並べ替えを実行してみましょう。

f:id:kmynews:20170226113630p:plain

はい、何も起きませんね!
一番最後の「あいうえお」が最初に来てほしいのに、無理っぽいですね(´・ω・`)

でも、実は何も起きていないわけではありません。
GoogleのREST APIのドキュメントを見てみますと、

REST API は並べ替えられていない結果を返す: JSON インタープリターは、結果セットに対して並べ替えを一切適用しません。orderBy を startAt、endAt、limitToFirst、または limitToLast と組み合わせてデータのサブセットを返すことができますが、返される結果は並べ替えられません。したがって、並べ替えが重要な場合は、結果を手動で並べ替える必要があります。

とあります。
並べ替えは絞り込みと併用して初めて意味をなします。
でも、返される結果そのものは並び替えられてませんよ、と。
ややこしいですね!!!

件数指定して絞り込み

というわけで、本当に並べ替えが実行されているのか、件数を指定して絞り込むことで試してみましょう!

最初の3件に絞り込みます。
「あいうえお」というデータは一番最後にありますから、並べ替えなしだとこの中には入っていないはずです。
でも、並べ替えがちゃんと働いていれば、結果の中に含まれているはずです。
さて、どうなんでしょう?

f:id:kmynews:20170226114622p:plain

おお、入ってますね!
並べ替えられていないことを抜きにしても、入ってますね!これをC#のほうで手動で並べ替えるらしいです。
なんともややこしい。

ちなみにLimitToLastは、最後から数えた結果を返します。
OrderByDescといったメソッドはありませんので、これの代わりに使ってくださいということだと思います。多分。

リアルタイム監視

今までDatabaseなんてゆうてましたが、ファイヤー!公式では、正式にはRealtime Databaseと呼ばれています。
Realtimeです。
Realtimeです。

データの変化をリアルタイムでキャッチする方法が用意されています!なにそれかっこいい

これは、Rx(Reactive Extensions)という考え方がちょっとだけ入っていますが、そこまでつっこんだものでもないので知らない人でも大丈夫かな?と思います。

_realtimeDatabaseWatcherの型はIDisposableになっています。
コードから想像できるとおり、sample/pathにあるデータの配列の動向を監視します。

このメソッドは、ログイン成功した時に呼び出されるよう設定してみました。
これを実行してみます。

f:id:kmynews:20170226115513p:plain

あやや、ログインしただけなのに追加が検出されてますね。
すでに追加されたあとのデータであっても、容赦なくここに流し込まれてしまうようですね。

ここで、新しいデータを追加してみます。

f:id:kmynews:20170226115704p:plain

データ保存したよというメッセージだけでなく、監視のところにもデータ追加のメッセージが表示されていますね。
ここでいっぺん、Firebaseコンソールから適当なデータの中身を変更してみましょう。

f:id:kmynews:20170226115838p:plain

f:id:kmynews:20170226115846p:plain

データの追加なのか変更なのかは検知できません。まとめて処理するしかないみたいです。
どうしても検知したい場合は、データにIDを設定するなりしたほうがよさそうです。

さて、データを削除してみましょう。

f:id:kmynews:20170226120028p:plain

f:id:kmynews:20170226120037p:plain

どのデータが削除されたかまでは言ってくれませんが、削除は確かに通知されました。
何かと面倒です。

まとめ

ファイヤー!

ここまでのソースをGitHubにプッシュしました。

github.com

次回は、ファイヤー!APIキーの扱い方について、あすかが勝手に考えたことを記事にしてみます。
次回でファイヤー!のお話も終わりかな―!なんて思ってます!

kmycode.hatenablog.jp