Firebaseの技術情報サイト

Firebaseの技術情報サイト

Firebase活用の為の技術情報サイトです

Firebaseストレージへのアップロード

Firebase ストレージへのアップロード

前回の記事は Firebase ストレージのデータ(ファイル)へのアクセスを中心にお届けしました。今回は、Firebase ストレージにデータ(ファイル)を保存する方法をお届けします。

コンセプトは Firebase のストレージのデータ(ファイル)にアクセスするのと似ています。基本的に、「ファイルの場所(パス:path)」と「ファイルの名前」を決めれば Firebase ストレージにデータ(ファイル)を保存する事ができます。

誰がデータを保存するのか?

Firebase ストレージにデータ(ファイル)を保存する際に最初に考える事は、「誰」がデータ(ファイル)を Firebase のストレージに保存するのかを理解することが大切です。

写真や動画を投稿する様なサービスは、サービスの利用者がデータ(ファイル)をアップロードすることになります。一方で、オンラインコンテンツを Web ページを介して提供する様な場合は、Web サイトを運営する側がデータ(ファイル)をオンライン上に用意することになります。

このように、誰がデータ(ファイル)を Firebase ストレージに保存するかで、その方法も変わってきます。また、Firebase ストレージにあるデータ(ファイル)をどの様にアプリやサービスで扱うかでも変わってきます。

オンラインコンテンツなどの配信の場合

オンラインコンテンツの配信のように、Web サイトを運営する側でデータ(ファイル)を用意する場合、敢えてプログラムでサポートしないでも良い場合がたくさんあります。

これは、Firebase コンソールから Firebase ストレージにデータ(ファイル)をアップロードする事ができるからです。大抵のサービスならばこれで十分実用になります。

自由にフォルダの作成もできますし、ファイルのアップロードも簡単に行えますし、ダウンロードのためのリンクも取得できます。この既存の機能で十分な場合は敢えてプログラムでアップロードする仕組みを提供する必要はありません。

Web サイトの利用者がデータをアップロードする場合

一方で、Web サイトの利用者が投稿するなど、データ(ファイル)をアップロードする場合、Firegbase コンソールを利用することはできませんので、提供するサービスの機能の一部として、データ(ファイル)をアップロードする機能が必要になります。

データ(ファイル)を Firebase ストレージにアップロードするのは、基本的に読み出しと大きな差はありません。「場所」と「ファイル名」を指定すればシンプルなコードで実現が可能です。

funciton upload(e: React.ChangeEvent<HTMLInputElement>) {
    if (e.target.files && e.target.files[0]) {
      const file: File = e.target.files[0];
      const storeageRef = firebase.storage().ref();
      const fileRef = storeageRef.child("post/2021/Feb/" + file.name);
      fileRef.put(file).then((snapshot:firebase.storage.UploadTaskSnapshot) => {
        console.log("アップロードが完了しました");
      });
    }
  }

基本のコードはこれで可能です。あとは、React を使う場合には、ファイルを選択するフィールドから上の関数を呼び出せばファイルのアップロードができます。

<input
  type="file"
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => upload(e)}
/>

実際のサービスではもう少し細かい配慮が必要です!

機能的には上に挙げたようなコードを書けばファイルのアップロードは可能です。 しかし、実際に Firebase ストレージにファイルのアップロードをするのが、サービスの利用者の場合もう少し、細かい配慮が必要になります。

ファイルのアップロードが成功したのか失敗したのかを知らせる

これがとても重要です。特にサイズの大きなファイルを Firebase ストレージにアップロードする場合、多少時間がかかる場合もあります。その際は、ファイルのアップロードが終わったのかどうかも利用者に知らせた方がトラブルも少なくなります。

例えば、何も反応がないと、利用者は何度もファイルのアップロードをトライしたり、上手くアップロードできないと思ってしまう場合もあります。

Firebase のドキュメントを見ると、参考コードにはこうしたファイルのアップロード中の進捗状況をチェックする様なコードが例として紹介されています。

結果だけでなく、大きなファイルをアップロードすることが想定される場合には進捗状況を利用者に知らせる様にすると、利用者が勘違いして操作をすることを防ぐ事ができます。

function upload2(e: React.ChangeEvent<HTMLInputElement>) {
  if (e.target.files && e.target.files[0]) {
    const file: File = e.target.files[0];
    const storeageRef = firebase.storage().ref();
    const fileRef = storeageRef.child("post/2021/Feb/" + file.name);
    const task: firebase.storage.UploadTask = fileRef.put(file);
    task.on(
      "state_changed",
      (snapshot: firebase.storage.UploadTaskSnapshot) => {
        // アップロードの進捗状況
        const progress: number =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        switch (snapshot.state) {
          case firebase.storage.TaskState.PAUSED:
            console.log("停止中");
            console.log(progress.toFixed(2));
            break;
          case firebase.storage.TaskState.RUNNING:
            console.log("アップロード中");
            console.log(progress.toFixed(2));
            break;
          default:
            console.log(progress.toFixed(2));
            break;
        }
      },
      (error) => {
        // アップロード失敗
        console.log("アップロードに失敗しました");
      },
      () => {
        // アップロード成功
        console.log("アップロード完了");
      }
    );
  }
}

読み込みの場合は、ダウンロードが殆どで実際にデータを受け取る処理は、Web ブラウザが行うので処理はシンプルですが、利用者が Firebase ストレージにアップロードする場合は、プログラムでユーザーフレンドリーな処理が要求されます。

プログラムからアップロードするもう一つの理由

Firebase のストレージのデータ(ファイル)を利用者に提供する場合は、Firebase コンソールの利用が便利と書きました。実は、Firebase コンソールを使わずにプログラムでアップロードをした方が便利なケースが利用者にデータ(ファイル)を提供する場合でもあります。

それはメタデータをアップロードの際にファイルと一緒に保存する場合です。

メタデータをファイルと一緒に保存しておくと、ファイルの情報(リファレンス)を取得した時にメタデータを一緒に取得できます。これを利用すると、ファイルの一覧などを表示する際に単にファイル名だけではなく、ファイルの種類などの情報を一緒に表示することが可能になります。

これができると、より利用者に使いやすいサービスが実現できるのでサービスの価値も向上します。

const metadata: firebase.storage.UploadMetadata = {
  contentType: "text/html",
  customMetadata: {
    topic: "ブログの投稿",
    time: "2021-202-24",
    summary: "投稿データのサンプルです",
  },
};
const task = fileRef.put(file, metadata);

上の例では、ブログの記事を HTML ファイルで、タイトルと日付をメタデータとしてファイルと一緒に保存しています。こうした情報が添付されているとファイルの一覧もよりわかりやすいものにする事ができます。

利用者がデータ(ファイル)をアップロードする場合でも、投稿者や投稿時間などを添付するとサービスで表示する際に利用できます。

このデータは、ファイルの場所(リファレンス:reference)を取得すれば、「fileRef.getMetadata()」で取得できます。

まとめ

Firebase ストレージにデータ(ファイル)をアップロードする場合、誰がデータを Firebase ストレージに保存するかによってその方法を決める必要があります。

特に利用者がデータ(ファイル)を Firebase ストレージにアップロードする場合は、利用者が勘違いしないように、処理の状況を上手く表示することが良いサービスを作るコツです。

また、プログラムを利用して Firebase ストレージにアップロードする場合は、ファイルと一緒にメタデータと呼ばれるファイルの詳細情報を添付することができます。この情報を Web サービスの表示などに利用するとより魅力的なサービスの実装ができます。

利用者に使いやすいサービスはより付加価値の高いものになるのでちょっとした工夫でもユーザーのサービスに対する印象は大きく変わります。