FirebaseでReactアプリを作る際のDBアクセスサンプル


# はじめに
連載の3回目です。今回はアプリ側のFirebaseコードを中心に解説します
本当はサンプルアプリを作ろうと思ったのですが、
仕様の考慮漏れで課金プランでないと動かせないことが分かり断念しました

これまでの記事↓
[Firebase超概要](https://qiita.com/ozota/items/a8db60cf167052cff22b)
[Firebase+Reactの開発環境構築とはまりどころ解説](https://qiita.com/ozota/items/2afff1267ef0d7524725)


# Hostingからアクセスする
## パッケージインストール
`npm install firebase`でfirebaseのパッケージをインストールします。

## clientで使う初期化情報の取得
APIキーやアクセス先DB情報等を取得して、FirebasseのクライアントSDKの初期化をします。  

* ブラウザでFirebase Consoleを開き、左メニュー上にある「Project Overview」をクリック 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/e86643be-8599-ae9d-bc4b-d9f6dbb1bea1.png)

* 中央上部にある「+アプリを追加」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/66336154-d543-e2fe-6006-a10b73f0b319.png)

* Webサイトの場合は「</>」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/e582882b-531f-1aba-b2e7-ce8f32e40ecf.png)

* ポップアップが出てくるのでコードをコピー
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/b7f9273a-5b55-8ff8-1570-b38ed24543cb.png)

* 「src/index.js」に初期化コード貼り付けます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/1891b79a-ef71-2631-8ab0-562350056167.png)

 
  * ちゃんとやる場合はconfig部分を別jsonファイルに分けて読み込むといいと思います。今回はそのまま貼り付けます

  * APIキーを張り付けるという結構怖いことを言ってますが、これは漏れても大丈夫なやつです。
  * デフォルトで`https://<project-id>.firebaseapp.com/__/firebase/init.js`に公開されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/bb3125e6-db42-0556-e520-276e26f2dc8a.png)

  * 別のところで使う、管理者権限でアクセスする際に使う`private_key`を含むconfigは絶対漏れちゃダメなやつです。

## Firestoreへアクセスさせてみる
FirebasseのクライアントからFirestoreへアクセスさせてみます。

### Firestoreのだいたいのデータ構造
* 「ドキュメント」と「コレクション」の入れ子構造になっています
  * 「ドキュメント」：だいたいJsonオブジェクトと思えばいいです。
  * 「コレクション」： だいたいドキュメントの集合です。
  * "だいたい"と言っているのは、細かいことを割愛するためです。

### Firestoreの初期化コードを追記

```javascript:src/index.js
firebase.initializeApp(config);
// この3行を追記
const db = firebase.firestore();
const settings = { timestampsInSnapshots: true };
db.settings(settings);
```

### ためしにFirestoreにデータを入れてアクセスさせてみる
* Firebase consoleの「Databaseを選択します」  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/145658bf-5877-0769-0d67-3109f218ba57.png)
* コレクション・ドキュメントを追加します  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/ace99196-913e-2215-cc8d-66d681fd5579.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/9d339c89-7013-5892-3dc4-96f3ae5e0fca.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/4482caf2-2062-3827-2404-b9130ae1bdc6.png)

  * 結果をFirebase consoleで確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/3e622d21-1b08-ec26-212c-2a78c8d00f5c.png)


* DBアクセスコードをApp.jsに追加します

```javascript:src/App.js
...
  async componentDidMount() {
    const db = firebase.firestore();
    const docRef = db.collection("gallery").doc("testDoc");

    const doc = await docRef.get()
    console.log(doc.data())
  }
...
```

  * ブラウザで表示するとDBのtestドキュメントの中身がコンソールに出ます  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/0f91a325-609f-8971-4043-750d330fdb63.png)

* その他のコードの書き方は[マニュアル](https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja)にサンプル付きで書かれています

# firestoreのアクセスルール
* Database > ルール　から設定を確認できます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/d5d9d6f3-5682-f0dc-c54c-987f6d7e585a.png)

* `match ...`となっている部分が対象のコレクションやドキュメントの指定です
* その中にある`allow read, write;`の部分が許可内容です
  * 次のように`if`を付けて制限することができます。これは常に拒否と同等です
     ![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/8045e28d-f2e2-10e9-896e-a70276340b7f.png)

  * クライアントからアクセスしてもエラーが出るようになります
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/8ff81d71-a8f4-7f62-2467-f1233de42f7e.png)

* 詳細は[Firestore rules tips](https://qiita.com/sgr-ksmt/items/1a731fdadf06119d35fc)に詳しく解説されています

* 注意点としては、「[Firebase Admin SDK](https://firebase.google.com/docs/admin/setup?hl=ja) 」を使った場合はルールを無視してアクセスできることです。なのでFirebase Admin SDKのクレデンシャルは漏れてはいけません

# functions等から管理者権限で操作する
* 管理者権限のキーを発行します
* firebase consoleの![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/22ef86ec-41e7-e866-5b02-99e8c4c4f4ab.png)から「サービスアカウント」を選択します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/c8ddbe77-baf2-9545-481f-c54852e85413.png)

* ![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/0a847e1b-1521-a0f9-ae4d-da533245e7e8.png)から秘密鍵を生成します。jsonファイルがダウンロードされます

* functionsディレクトリで`npm install firebase-admin`します
* ダウンロードしたjsonを配置して、読み込むアプリを書けば使えるようになります
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/7e919586-dc0e-8b83-bed9-31aa1495e257.png)
* 使い方は`const db = admin.firestore();`として`db`オブジェクトを作る以外は基本的に変わりません