DatastoreとFirestoreとApp Engineの関連

# 注意書き

この記事は2017年12月の記事です。
現在、Google Cloud FirestoreはUPDATEされて、以下の内容とは異なります。
新しい記事はお待ち下さい！

# 記事

[Cloud Firestore](https://firebase.google.com/docs/firestore/) がBetaで公開されました。
Cloud Firestoreは、Firebase Realtime Databaseの後継に当たるサービスです。

Firebase Realtime DBに存在していたリアルタイム更新やデータベースルール, オフライン機能や、Firebase Authとの連携などを受け継いでいます。

大きく変わったのはバックエンドです。
Firebase Realtime DBは、もともとGoogleが作ったものではなく、Googleが買収したサービスでした。
買収後、FirebaseはAuth, Push通知, Analytics, Remote Configなどなど様々な機能が追加されていきましたが、Firebase Realtime DBは抜本的な機能が増えたりすることはありませんでした。

そして、抜本的にUpdateが入ったのが今回のFirestoreです。
バックエンドをGoogle Cloud Datastoreに差し替えて、機能を拡張し、Availabilityを向上させることを狙っています。
たとえば、ソートについてはDatastoreのIndexを利用することで、Firebase Realtime DBと比べてソート条件の選択肢を大幅に増やしています。

さて、そんなFirestoreですが、まだベータで公開されたばかりなので、色々と気を付けることがあります。

## Cloud Firestoreの始め方

https://console.firebase.google.com/ からProjectを作成するか、GCP ProjectのImportを行います。
GCP ProjectをImportする場合、そのProjectがまだApp EngineかDatastoreを利用していない必要があります。

<img width="1393" alt="firestore-start.png" src="https://qiita-image-store.s3.amazonaws.com/0/15640/010ecfff-afe0-ed6a-811f-9037b76d18e4.png">

DatabaseメニューからFirestoreを選択すると、Firestoreを利用できます。
もし、すでにApp Engine or Datastoreを利用している場合は以下のようにエラーになります。

<img width="675" alt="sinmetal-firestore-2_–_Database_–_Firebase_console.png" src="https://qiita-image-store.s3.amazonaws.com/0/15640/ee9018f3-014d-a00b-7340-0a578d3911c0.png">

あとはドキュメントに従って、好きなクライアントから呼び出せばOKです。
データを入れると以下のような感じで見えます。

<img width="1127" alt="firestore-console.png" src="https://qiita-image-store.s3.amazonaws.com/0/15640/df5d4bcc-4207-fcf2-0537-b81b2dd5129c.png">


## Datastoreとの関係

Firestoreは、Firebase Realtime DBの後継として登場したわけですが、Firestoreを有効にしているGCP ProjectのDatastoreのConsoleを表示すると以下のような画面が出てきて、DatastoreのConsoleを利用することはできません。

<img width="691" alt="datastore.png" src="https://qiita-image-store.s3.amazonaws.com/0/15640/531dd3cb-8ab6-846d-8f7d-abb98bbb8af4.png">

そして、この画面のメッセージには、Firestoreは **Datastoreの後継** だと書かれています。
確かに、FirestoreはDatastoreの機能をほぼすべて受け継いだ上で、追加の機能を足しているような状態になっています。
まだ、ベータ公開されたばかりなので、荒削りなところはありますが、Datastore使いから見ても魅力的なサービスです。

### FirestoreとDatastoreの併用

Firestoreを利用していると、DatastoreのConsoleは使えないのですが、後ろではDatastoreを利用しているので、DatastoreのAPIを利用して、データを登録しても、Firestoreに反映されます。
そのため、 [Google Cloud Dataflow](https://cloud.google.com/dataflow/?hl=ja) のDatastore IOを利用して、データの読み書きを行うことができます。
初期データの投入なんかはDataflowから行うのが簡単です。

## App EngineとFirestore

App Engineをすでに利用しているGCP ProjectではFirestoreを使えませんが、Firestoreを初めてから、App EngineをDeployすることは可能です。
この場合、App Engineは `us-central-1` となります。App Engine & Cloud Datastoreはすでに `asia-northeast-1` にいるわけですが、おそらくFirestoreは現状USにしかいないのでしょう。
GAになるころには、 `asia-northeast-1` に来るように信仰心が試されます。

App EngineからFirestoreを使う方法ですが、２種類あります。
1つはFirestoreだと思わずに、普通にApp EngineにビルトインされているDatastore Libraryを利用してアクセスします。
Firestoreは普通にDatastoreにデータを入れているので、普通に読み書きできます。
もう1つはFirestoreのLibraryを利用する方法です。
[Cloud Client Library](https://cloud.google.com/firestore/docs/apis) が用意されているので、これを利用します。
オフラインDBや、リアルタイム同期などのサポートはApp Engine Standardでは利用できませんが、普通に読み書きするのは可能です。
ただ、App Engine StandardでCloud Client Libraryを利用した場合、後ろではgRPCを利用します。
gRPCを利用する時に、App Engine Socket APIを利用するので、Quotaに注意が必要です。

どちらの方法でも、App EngineからFirestoreを利用した場合、App EngineのConsoleからはFirestoreとして表示されます。
現在、Firestoreの料金体系はDatastoreと同じような感じです。 
なぜかFirestoreには、Datastore Small Ops相当のものが書いてないのが、ちょっと気になるぐらいです。

* https://cloud.google.com/firestore/pricing
* https://cloud.google.com/datastore/pricing

<img width="1487" alt="App_Engine_Dashboard_-_sinmetal-firestore-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/15640/b44b8132-8466-98fa-25ff-cc6215784953.png">


## 現時点での課題

さて、ベータなので、やっぱり課題はまだまだあります。
~~現時点で僕が一番感じている問題は **パフォーマンスが悪い** です。
おそらく、FirestoreのAPIを受け取っている何かがDatastoreとやりとりしてるんじゃないかと思ってるんですが、ぼちぼち遅いです。
まぁ、Datastore自体がそんなに1回ずつのやり取りが早いDatabaseじゃないので、びびるレベルで早くするのは難しいような気はちょっとしてるけど、それにしてもちょっと遅くない！？みたいなところが少しあります。
実際、App Engine Standard for GoからビルトインのDatastoreを呼ぶと50ms ~ 100msぐらいですが、Firestoreを呼ぶと200ms ~ 4500msぐらいかかっています。
Socket APIが間に入っているとは言え、さすがに1件putに4500msは遅くない！？みたいな気持ちです。
だんだん早くなっていってくれるのを祈る or 早くやり取りできるデータ構成を考える 必要がありそうな感じです。~~
**パフォーマンスは改善され, Cloud Datastoreを直接実行するのと同じぐらいになりました**

Datastoreとの併用については、将来的にはできるようにするみたいなことを言ってたという噂を聞いたので、FirestoreがDatastoreをガッと奪っている感じにベータの間だけで、将来的には1つのGCP Projectで同居できるようになりそうです。

## さいごに

Datastoreジャンキーの僕としてはFirestoreは非常に期待しているサービスです。
Firebase Realtime DBは便利なサービスですが、Availabilityの問題やGCPのサービスたちとの連携に少々課題がありましたが、Firestoreはそれを解決してくれるぴったりなサービスです。
Datastoreを使うのをやめて、Firestoreを使うようにするような世界がいつ来るかは分かりませんが、これからはそれも頭の片隅においてアーキテクチャを考えていこうかなと思います。

現時点のFirestoreでのアーキテクチャを理解するためには、Datastoreを理解する必要があり、Datastoreを理解するためにはBigtableを理解する必要があるみたいなところが、ちょっとあるかもしれない。
その辺りもいずれ書けたら書こう。

Cloud Firestoreに興味がある人は、 GCPUGのSlackの `#g-firestore_ja` でコミュニティのメンバーがうだうだ言ってるので、参加してみるとよいかも。
GCPUG Slackへは http://slack.gcpug.jp/ から参加できます。