firebase storageから音声ファイルをダウンロードして再生

# この記事で書くこと
Firebaseの環境構築や、firebaseのインストールは参考文献に記載しているページに詳しく記載されていますので割愛します。
この記事は、「AngularのプロジェクトにFirebaseを導入する」の[angularfire2とfirebaseをインストール](https://qiita.com/Yamamoto0525/items/437a2884c0c51f5a3af8#angularfire2%E3%81%A8firebase%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)までを終了した状態から開始するものとします。
また、AngularFire2を用いてFirebase Storageからファイルのダウンロード、ダウンロードした音声ファイルの再生について記載します。

>angularfire2とは
>Angularで使い勝手がよくなるようラッピングされた、Firebaseクライアントです。
>RxJSを使ってクライアントとFirebase間の同期を行うのが特徴で、現在（2018年9月）のところCloud Firestore、Realtime Database、Authentication、Cloud >Storage、Firebase Messaging、Cloud Functionsをサポートしています。
>
>引用元
>[AngularのプロジェクトにFirebaseを導入する - angularfire2とは](https://qiita.com/Yamamoto0525/items/437a2884c0c51f5a3af8#angularfire2%E3%81%A8%E3%81%AF)

# ソースコード
この記事では以下の私が作成したサンプルを基にして説明を行います。
https://github.com/roottool/OrgaSound

# プロジェクトにFirebase Storageを導入する

## angularfire2のAngularFireStorageModuleをインポートする
今回はFire Storageを使用するので、AngularFireStorageModuleをインポートします。

```/src/app/app.module.ts
// 追加
import { AngularFireStorageModule } from '@angular/fire/storage';

@NgModule({
  imports: [
    // 追加
    AngularFireStorageModule
  ]
})
```

## Firebase Storageを導入する
作成したプロジェクトでは、ダウンロードから再生までのロジックをサービスとして分離しています。

```/src/app/services/play.service.ts
// 追加
import { AngularFireStorage } from 'angularfire2/storage';

  constructor(
    // 追加
    private afStorage: AngularFireStorage
  ) { }
```

# Firebase Storageからファイルをダウンロードする

```/src/app/services/play.service.ts
export class PlayService {
  play() {
    const itemRef = this.afStorage.storage.ref('filePath');

    itemRef.getDownloadURL().then((url) => {
    })
    .catch((error) => {
      this.outputError(error);
    });
  }

  outputError(error) {
    // A full list of error codes is available at
    // https://firebase.google.com/docs/storage/web/handle-errors
    switch (error.code) {
      case 'storage/object-not-found':
        // File doesn't exist
        console.log('Object not found');
        break;
      case 'storage/unauthorized':
        // User doesn't have permission to access the object
        console.log('Permission denied');
        break;
      case 'storage/canceled':
        // User canceled the upload
        console.log('Canceled upload');
        break;
      case 'storage/unknown':
        // Unknown error occurred, inspect the server response
        console.log('Unknown error');
        break;
    }
  }
}
```

`this.afStorage.storage.ref('filePath')`でfilePathへのストレージ参照を作成します。
作成したストレージ参照を基に、`itemRef.getDownloadURL()`でダウンロードURLを取得します。
取得が完了したかエラーかで、`then((url) => {})`か`catch((error) => {})`の内部が実行されます。
`url`は取得したダウンロードURL、`error`はエラー情報が格納されます。
エラー処理は[Firebase Storageのドキュメント](https://firebase.google.com/docs/storage/web/download-files?hl=ja)のコピーです。

# ダウンロードした音声ファイルを再生する

```/src/app/services/play.service.ts
export class PlayService {
  constructor(
    private afStorage: AngularFireStorage
  ) { }

  play() {
    const itemRef = this.afStorage.storage.ref('filePath');

    itemRef.getDownloadURL().then((url) => {
      const sound = new Audio(url);
      sound.play();
    })
  }
}
```
ダウンロード成功時に取得したURLを基にAudioオブジェクトを作成し、`sound.play();`で再生します。


# 参考文献
- [Firebaseの環境構築](https://qiita.com/Yamamoto0525/items/fb23707831ff6d181544)
- [AngularのプロジェクトにFirebaseを導入する](https://qiita.com/Yamamoto0525/items/437a2884c0c51f5a3af8)