Firebase Storageからjsonファイルを読み込む

## 概要

FirebaseのStorageに配置したjsonファイルをVue.jsのアプリケーションから読み込んでみます。
Vue.jsのセットアップに関しては割愛しますが、VueCLI3.0で作成したプロジェクトを使っています。

||version|
|---|---|
|MacOS|Mojave 10.14.2|
|vue|2.5.17|
|vuex|3.0.1|
|Firebase|5.7.1|

## Firebaseの設定

何はともあれまずはFirebaseでプロジェクトを作成します。

https://console.firebase.google.com

トップページでwebアプリで利用を選択すると、このscriptタグを埋め込めやと出てくるので素直に従います。

```html:index.html
<!DOCTYPE html>
<html lang="en">
...
    <div id="app"></div>
    <script src="https://www.gstatic.com/firebasejs/5.7.1/firebase.js"></script>
    <script>
      // Initialize Firebase
      var config = {
        apiKey: "hogefuga",
        authDomain: "hogefuga.firebaseapp.com",
        databaseURL: "https://hogefuga.firebaseio.com",
        projectId: "hogefuga",
        storageBucket: "hogefuga.appspot.com",
        messagingSenderId: "012346789"
      };
      firebase.initializeApp(config);
    </script>
  </body>
</html>
```

## Storageにファイルをアップロード

今回はアップロードは手動で行います。
Storageのコンソールを開いてファイルをアップロードしましょう。

以下はサンプルなので中身は何でも良いです。

```json:result.json
[
  {
    "name": "有馬記念",
    "ground": "芝",
    "distance": "2500",
    "grade": "G1",
    "horses": [{
      "name": "オジュウチョウサン",
      "gate": 1,
      "number": 1,
      "sex": "牡",
      "age": "7",
      "handi": "57",
      "odds": "15.1",
      "rank": "7",
      "jockey": "武豊"
    },
    (中略)
    ]
  }
]
```

## Storageのルールを変更

WebアプリからStorageを参照するにあたっていくつか設定が必要になります。

### 参照権限の設定

デフォルトの設定だと認証されたユーザーしかStorageにアクセスできません。
今回はシンプルに動作確認をするため参照であれば誰でも可能なように権限を変更します。
念のためアップロードするデータには気を付けてください。

Storageコンソールのルールタブから編集できます。

```diff
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
-      allow read, write: if request.auth != null;
+      allow read
+      allow write: if request.auth != null;
    }
  }
}
```

### CORSの設定

CORS = Cross-Origin Resource Sharing
詳しい説明は割愛しますが(理解できていないだけ笑)、
この設定をしないとブラウザ経由でStorageからのファイルの読み込みが許可されません。

#### gsutilのインストール

https://cloud.google.com/storage/docs/gsutil_install

#### CORS設定の反映

任意のディレクトリで以下のjsonファイルを作成します。

```json:cors.json
[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
```

その後、作成したjsonが存在するディレクトリで以下のコマンドを実行してください。
`gs://<your-cloud-storage-bucket>`の部分はStorageコンソールに表示されています。

```
gsutil cors set cors.json gs://<your-cloud-storage-bucket>
```

## ロジックの実装

あとは実際にファイルを読み込むロジックを実装していきます。

### axiosのインストール

jsonデータ取得のリクエスト用にaxiosを利用します。

```shell
npm install axios
```

### javascriptの実装

Vuexを利用しているのでstoreのactionsにメソッドを実装していますが、
手元に環境に合わせて任意の場所に処理を実装してください。

```javascript:store.js
import Vue from 'vue'
import Vuex from 'vuex'

import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    raceData: []
  },
  mutations: {
    setData(state, payload) {
      state.raceData = payload.raceData
    }
  },
  actions: {
    readJson({ commit }) {
      // storageの情報を取得
      const firebaseStorage = firebase.storage()
      // ファイル名を指定して情報を取得
      // これはあくまでファイルに関する情報でありファイルの中身ではない
      const fileRef = firebaseStorage.ref('result.json')
      // getDownloadURLでファイルにアクセスするためのURLを取得できる
      fileRef.getDownloadURL().then(url => {
        // 取得したURLにGETリクエストを投げる
        return axios.get(url)
      }).then(response => {
        // 返ってきたresponseのdataプロパティにjsonファイルの中身が格納されている
        const data = response.data
        console.log(data)
        commit('setData', { raceData: data })
      })
    }
  }
})
```

実装した処理を実行すると、
ブラウザのコンソールを見ると取得したjsonデータが出力されているはずです。

## 参考

### 公式ドキュメント

- [ファイルのダウンロードについて](https://firebase.google.com/docs/storage/web/download-files)
- [CORSについて](https://cloud.google.com/storage/docs/cross-origin)