【超簡単】Firebase で無料で作るハイスコアDB : APIキー制限設定忘れずに！！

# 前回までの砂漠のひつじ

無料プログラム学習用ピコピコゲーム[砂漠のひつじ](https://kaku3.github.io/the-sheep-in-the-desert/)を作成しつつ、その過程を記事にしている。
本記事はハイスコア実装編4回目として、無料DBの選定、調査の経過として、Firebaseアカウント作成から簡単なDB操作までを行っている。

前回までの記事では、Azure CosmosDBの動作を一通り確認しアーキテクチャが必要以上に複雑と感じFirebaseを調査することとしていた。

前回までの記事：
- [Azure Cosmos で無料で作るハイスコアDB(1)](https://qiita.com/kaku3/items/c64eb4acd97ab8e41592)
- [Azure Cosmos で無料で作るハイスコアDB(2) : APIとデータモデルとAzureテーブル](https://qiita.com/kaku3/items/d3e675790ce36ee54435)
- [Azure Cosmos で無料で作るハイスコアDB(3) : コア(SQL)](https://qiita.com/kaku3/items/fe70fd0ff2e56330453d)


今回の調査を終えての結論を述べると、学習コスト / 利用しやすさは以下の様に感じた。

**Firebase Cloud Firestore(簡単) << AWS DynamoDB <<<(超えられない壁)<< Azure CosmosDB(難しい)**

以下、Firebase登録から、レコード登録、取得および**APIキー制限**までを解説する。
APIキー制限を行わないと悪意のある第三者からアクセスし放題になるので注意が必要。

# Firebaseアカウント登録

Googleアカウントを持っていれば、一切情報入力なしで一瞬で登録完了する。

[Firebase:料金](https://firebase.google.com/pricing?hl=ja)ページのファビュラスではなくジェネラスなリミットの**Sparkプラン**の項目の内容に目を通して、「無料Sparkプラン」項目にある[すぐに開始可能]ボタンを押下。

![00_firebase_register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/880f12c7-36d9-a40d-2036-3fa3295b2e8d.png)


# プロジェクト作成

Firebaseアカウント登録が完了したらコンソールへ移動。
[プロジェクトを追加]ボタンを押下しプロジェクトを作成する。

プロジェクト名を入力し、GoogleAnalyticsの利用設定を行えば完了。
無料プロジェクトの作業はアクセス数ぐらいしかモチベーションがないので利用する設定にしておいたが、画面キャプチャは省略している。

![10_firebase_console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/e00ee3ed-c467-1ab5-e5f9-b3461d38ce26.png)
![20_firebase_project_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/fe89bfab-1b20-9edc-5bd8-3ff68d441ec3.png)

# DB設定

## Cloud Firestore

プロジェクトの作成が終わったら、プロジェクトHome画面左のナビゲーションバーよりCloud Firestore を選択し、[データベースの作成]を押下し、任意の名前のデータベースを作成する。

![30_cloud_firestore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/66627686-45af-4f21-2b58-8ecec14f7f8f.png)

作成時、テストモードにするとガバガバになるので注意が必要。

![31_cloud_firestore_test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/88757fcd-08d8-be7a-4b03-3a56f1c598c0.png)

ロケーションは、asia-northeast1を選択。

![32_cloud_firestore_location.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/526b9f40-d83a-982d-8371-8762244cad47.png)

## コレクションを開始

RDBで言うところのテーブルに相当するのがFirebaseのコレクション。
コレクション登録時にレコードを1件登録するUIになっているのは賛否ありそうだが個人的にはよいと感じた。

![40_db.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/9e7b5d7f-cf04-5061-3202-256359aed03c.png)

レコード登録時にドキュメントIDを省略すると自動で一意のIDが振られるのも好印象。

![41_db_collection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/c89bd25e-4465-d3c2-b14b-39641eea3209.png)
![42_db_collection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/6ecf79af-2b77-cdce-d2df-798e112d176a.png)

# アプリ設定

## アプリ作成

今回はWebページで利用するので、プロジェクトのHome画面より、[</>]ボタン押下。
任意のアプリの名前をつける。

![50_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/8fd3092f-3185-148c-299a-056e3157b9d3.png)
![51_app2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/f457ef65-2a95-90e3-d676-26b1a7fe8ac5.png)

※「このアプリのFirebase Hostingも設定します。」について
Firebase Hosting を使うと Firebase CLI の設定が簡単になったりするがお高い模様。
今回はCDNからFirebaseのライブラリを取得しており、GitHub Pagesで公開しているのでいずれにしてもチェックはしない。

## html に初期化コード追加

初期化コードが出力されるので、htmlにコピペする。

![53_app3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/5122a76c-9ffe-2a0e-d7ee-63c37516d72f.png)

コメントにTODOの記載がある通り、firestoreにアクセスするためライブラリを追加する。

``` index.html
<!-- firebase
執筆時点バージョンは、7.24.0。ドキュメントによりバージョン番号が異なる。
コンパネで取得できた初期化コードのバージョンに合わせるのがよさそう。
-->
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase-analytics.js"></script>

<!-- 利用したい機能を追加 -->
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase-firestore.js"></script>

<!-- 初期化部分は別ファイルにしておく -->
<script src="./firebase/init-firebase.js"></script>
<!-- firebase -->

```

## スコア登録処理(js)

collection名を指定して、add。
CosmosDBでやってた作業はなんだったのか。

``` sample.js
var db = firebase.firestore();
db.collection('scores').add({
    name: 'name',
    score: 1000
}).then((r) => {
    console.log(r); // 登録成功したレコードの内容を表示。r.id に一意のIDが設定されている。
}).catch((err) => {
    console.log(err);   // エラー内容を表示
})
```

## スコア取得処理(js)

コレクションに対して、where, orderBy, limit を指定して任意のレコード取得可能。
get()で全件取得も可能。

``` sample.js
// Queryを作る。where 句も対応しているが今回は不要のため未実装。
var q = db.collection('scores').orderBy('score', 'desc').limit(5);

// 非同期で取得。docsに配列形式で格納されており、.data() で json オブジェクトを取得できる。
q.get().then((r) => {
    for(var d of r.docs) {
        console.log(d.data());
    }
})
```

# APIキーに制限をかける【超重要】

勘の良い諸兄であれば、apiKeyを公開するソースに貼り付けてよいのか不安で作業が止まると思う。
推察の通りデフォルトでは**ソースをコピペした第三者からアクセスし放題**の状態となっている。

``` config.js
var firebaseConfig = {
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
};
```

ここまでの作業は画面の指示に従っていればできたのに、この作業だけなぜか一連のUIに組み込まれていない。よく分からないからFirebase Hosting を使おうと何度も挫けそうになった。

## APIとサービスにアクセス

[APIとサービス](https://console.cloud.google.com/apis/) にアクセスし、現在作成中のプロジェクトを選択し、ナビゲーションより認証情報を選択すると、[Browser key (auto created by Firebase)]というAPIキーが**警告と共に作成されている**のが分かるのでこれをクリックする。

![60_api1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/cf74b6a6-983b-370e-6ceb-d1c167ade7b4.png)


## アプリケーションの制限を設定

今回は、Git Hub Pages のURL(kaku3.github.io/the-sheep-in-the-desert/*)を、HTTPリファラー(ウェブサイト)として登録することにする。
この設定を行うと、デプロイ済みの本番環境からしか利用できなくなるので、アプリを2つ(prod, dev)作成し開発用のapiKeyは公開しないのがよさそうに思えた。

![61_api2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/c3070b98-02e7-29ab-277a-294d3631f6a4.png)

# おわりに

簡単過ぎてビックリしました。
APIキーがガバガバなのもびっくりしました。

次回は実際にアプリに組み込もうかと思います。