Googleに喧嘩を売るFirestoreの変態的かつ実用的なつかいかた

ゼンチン！ゼンチン！ドネシア！ゼンチン！


こんばんは、突然ですが、Firestoreって、めっちゃ便利ですよね。

でも、ぼくおもったんです。

これはもっと便利につかえると。

ただし、

ここから先を読むにあたり、つぎのことに注意してください。

- このやり方を、大きなプロダクトに突然「入れよう！」って言わない。**正論**の前に返り討ちに遭います:cop:
- 正論をお持ちの方。人間誰でも元は健気な赤ちゃんだったんです。**健気**な気持ちで読んで、くれぐれもお手持ちのマサカリは投げないように！:baby:
- **Google**の人のまえで、「Firestore便利っすよね！こんな使い方できますもんね！」って言わない:no_good:

ではいきましょう！

# こんなひとたちに、ありがたみ！

- 「管理画面をつくりたいけど、時間ないからまずは、**DBオペ**でデータを入れちゃうか..:frowning2:」
- 「管理画面にするほどのデータじゃないからソースに定数として含めているけど、たまに**『あの文言変えたいんだよね、、』**と言われてビルドし直している..:dizzy_face:」
- 「ほぼリアルタイムにデータをキャッシュをしたいんだけど、今そこまでやるぅ、、、？:rolling_eyes:」

# やりかた:walking:

- Firestoreで、「コンフィグデータ専用」のコレクションを1つ作成する
- サーバから、当該コレクションのリアルタイムアップデートを入手する

これだけです。

# 具体的に！

例をひとつ。

例えば、あなたのアプリケーション上で、突然、国名わけっこゲーム([さっきまでM-1見ていたので、、](https://twitter.com/search?q=%E5%9B%BD%E5%90%8D%E3%82%8F%E3%81%91%E3%81%A3%E3%81%93&src=typd))というミニゲームでキャンペーンをすることになりました！

今後も、もし流行ったら、明日もまた、国名わけっこゲームをしよう！となります。
そのときに、ゲームの参加者や、開始時間などは変わる、という設定です。
逆に、流行らなかったら、もうやることはありません。

エンジニア泣かせの仕様ですね。
でも、Firestoreなら大丈夫。


Firestoreでこんなコレクションを作成します。

<img width="999" alt="kokumei.png" src="https://qiita-image-store.s3.amazonaws.com/0/30181/4b8133f9-9e3d-2d3e-e609-6e7975f644db.png">

settings、というコレクションの中に、 `kokumei-wakekko-game` というドキュメントがあり、その下に、いくつかフィールドがあります。

1つのコレクションを、もう『スキーマ』とか、『行』、みたいな世界観を忘れて、上記のようにデータを入れておけば、次もう一度国名わけっこゲームを別の変数でやるとなっても、(Firebaseコンソールから、)10秒くらいでDBデータを書き変えて、準備は完了します。

しかも、国名わけっこゲームの最中に、『アッ配信日間違えてる！今すぐ終了しないと！』みたいなときに、
じゃあ家に帰ってPC開いて緊急リリース！とかしなくても、
手元のスマホでfirestoreのコンソールをピッと開いて、サッと変えてやればおわりです。

リアルタイムアップデートでサーバが取得しているので。

ちなみに実際にスマホで変えようとしたときのスクリーンショットがこちら。

![Screenshot_20181202-222426.png](https://qiita-image-store.s3.amazonaws.com/0/30181/5bc46aaa-042b-826e-3b44-c0d7e014f7f3.png)
↓　↓　↓　↓　↓　↓　↓
![Screenshot_20181202-222441.png](https://qiita-image-store.s3.amazonaws.com/0/30181/d6c98e16-9c31-a75a-ef7d-3dbabf17f49b.png)
↓　↓　↓　↓　↓　↓　↓
![Screenshot_20181202-222446.png](https://qiita-image-store.s3.amazonaws.com/0/30181/2d6e68b3-9b61-1b93-8fee-ea39a7009a14.png)

簡単にできそうでしょ。

イメージ湧きましたでしょうか？


この辺を既存の技術でガチでやろうとすると、
GUIは必要だわ、イベントをトリガーにリッスンするor定期的なキャッシュ機能必要だわ、色々めんどくさいですからね。

もうFirestoreをただの(**リアルタイムアップデート付き型ありGUI付きの贅沢な**)コンフィグファイル、とみなすということですね。

ちなみに、もう一つ並行でキャンペーン走るなら、もう一本ドキュメントを作ればいいし(※その場合は本記事下部の注意を読んでね)、
1ドキュメントで、iOSのinfo.plistみたいに管理しちゃってもいい。

まぁほんとうにinfo.plistみたいなもんですからね、この使い方。

# 使った結果どうなる？

↓[うち](https://www.hotspring-inc.jp/)のslackの風景。

<img width="334" alt="スクリーンショット 2018-12-02 22.04.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/30181/d13f49ee-a356-0eb0-b348-a562ee8d212e.png">

1分で即バリューがでるので、自分がスゴイエンジニアになったんじゃないか、と勘違いしたりします。

# ありがたみを整理

- PC/スマホ両用の管理画面が用意される
    - っていうかFirestoreのコンソール画面だけど
    - スマホでもok。緊急対応も楽々
- リアルタイムに情報が反映されるので、キャッシュも必要なし
- 何なら型がついてくる

# 注意すること！

これは、次の点で、正しい使い方と異なってます。
なので、それぞれ、実用してみて、問題がおこることもありました

### 1. スキーマがないゆえに
Firestoreデータをすべてexportして、すべてをBigQueryに突っ込もうとしたら、スキーマ読み取れない、で怒られました。

##### 対策
一括exportではなく、collectionを指定してexportもできます。それをBigQueryに吐き出せばok。

また、やってないけれど、1ドキュメントのみでやれば、それイコールスキーマ、になので、怒られないと予想してます(試してません)。

僕は複数ドキュメントを全然違うスキーマで入れていたので、かなりワルいです:imp:

### 2. リアルタイムアップデートで繋いでいるゆえに

コネクションが切れることがありました。
そもそも、サーバってずっと稼働してるじゃないですか。
いつまでリアルタイムアップデート接続しているのかなぁ、、ってやってみたら、1週間くらいしたらアカンくなってました。(GAEなので、間に再起動してますが)

##### 対策
ただ繋ぎっぱなしなだけでなく、3hおきにつなぎ直すようにしたら、ほぼほぼ切れることはなくなりました。っていうか、3hにする意味は本当に特にないので、もっと短くすべきです←


# (おまけ)Remote Configがほぼリアルタイムに反映してくれるようになったと聞いているけど？？

[そうなんですよね。](https://developers-jp.googleblog.com/2018/11/whats-new-at-firebase-summit-2018.html)

敢えて今回紹介したやり方をすることの意味をかくと、
Remote ConfigはConfigに寄りすぎていて、型がない。文字列 or JSONなんですよね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30181/f7dda24d-2595-c588-b8c0-3d065edc4925.png)

JSONデータをサクッと変えたり、スマホから変えたりしますか、というと厳しいよなぁと。

それだけでなく、Firestoreの方が高機能だし、たくさんの機能を流用して悪いことをあんなこともこんなことも、、、

・・・。
・・・・。
・・・・・。


えぇ、ちゃんと技術は正しくつかいましょうね！
Remote Config、使いましょう！

ちなみにまじめに、Remote Configは、環境によって値を変えることができたり、Firebaseの分析系ツールと連携して使えたりするので、本当にシステムコンフィグのリモート化や、PDCAを楽に回していく際に役立つと思います！




それでは、皆さん、2018年も、M-1お疲れ様でした！！

霜降り明星、優勝おめでとう！！！