[この記事は David East、デベロッパー アドボケートによる Firebase Blog の記事 "5 tips for Firebase Storage" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。]

David East


David East
デベロッパー アドボケート
お待ちかねの機能、Firebase デベロッパーのためのファイル ストレージがついに実現されました。Firebase Storage は、ユーザーが iOS 端末、Android 端末、ウェブで生成した画像やビデオなどのコンテンツをアップロードするためのスタンドアロン ソリューションです。他の Firebase のサービスと同様、サーバーは必要ありません。
Firebase Storage は、拡張性セキュリティネットワークの耐障害性に特化した設計になっています。
  • 拡張性: アップロードされたファイルはすべて Google Cloud Storage でバックアップされます。このストレージは、 数ペタバイト規模のデータに対応しています。
  • セキュリティ: ストレージ セキュリティ ルールによってファイルを保護し、特定のユーザーのみにアクセスが許可されます。
  • ネットワークの耐障害性: ネットワーク接続が不安定な場合、アップロードやダウンロードが自動的にリトライされます。そのため、自分で状況を確認する必要はありません。
このブログ記事では、Firebase Storage を活用するための 5 つのヒントを紹介します。説明はこのくらいにして、早速コードを見てみましょう。


1. ファイルのリファレンス ポイント

Realtime Database のことをよく知らなくても、Firebase Storage に簡単にデータを保存できます。Firebase Storage は、シンプルなフォルダとファイルの仕組みを使用し、データの構造化を行います。ファイルには、リファレンスを使ってアクセスします。

ウェブ
var storageRef = firebase.storage.ref("folderName/file.jpg");

iOS
let storageRef = FIRStorage.reference().child("folderName/file.jpg")
Android
StorageReference storageRef = FirebaseStorage.getInstance().reference().child("folderName/file.jpg");


リファレンスを使うと、ストレージ バケット内の指定の場所にあるファイルを操作できます。このストレージでは、既存のファイルのダウンロードや新しいファイルのアップロードを簡単に行うことができます。

2. メソッド 1 つでファイルをアップロード

リファレンスを取得したら、メソッド 1 つでファイルをアップロードできます。

ウェブ
var storageRef = firebase.storage.ref("folderName/file.jpg");
var fileUpload = document.getElementById("fileUpload");
fileUpload.on(‘change’, function(evt) {
  var firstFile = evt.target.file[0]; // get the first file uploaded
  var uploadTask = storageRef.put(firstFile);
});

iOS
let storageRef = FIRStorage.reference().child("folderName/file.jpg");
let localFile: NSURL = // get a file;

// Upload the file to the path "folderName/file.jpg"
let uploadTask = storageRef.putFile(localFile, metadata: nil)


Android
StorageReference storageRef = FirebaseStorage.getInstance().reference().child("folderName/file.jpg");
Uri file = Uri.fromFile(new File("path/to/folderName/file.jpg"));
UploadTask uploadTask = storageRef.putFile(file);

ウェブのバイナリ ファイルは、<input type="file" /> 要素で受信した File オブジェクトから取得します。iOS ユーザーは、メモリ内またはローカルからファイルをアップロードできます。Android では、ストリームを使ってアップロードすることも可能です。

3. タスクで進捗状況を監視

アプリに進捗インジケーターを作成したい場合、Firebase Storage を使うと簡単に実現できます。ファイルのアップロードやダウンロードを行うと、UploadTask または DownloadTasks が作成されます。これらのタスクから、ファイルのアップロードやダウンロードの進捗を監視できます。

ウェブ
var storageRef = firebase.storage.ref("folderName/file.jpg");
var fileUpload = document.getElementById("fileUpload");
fileUpload.on(‘change’, function(evt) {
  var firstFile = evt.target.file[0]; // get the first file uploaded
  var uploadTask = storageRef.put(firstFile);
  uploadTask.on(‘state_changed’, function progress(snapshot) {
     console.log(snapshot.totalBytesTransferred); // progress of upload
  });
});

iOS
let storageRef = FIRStorage.reference().child("folderName/file.jpg");
let localFile: NSURL = // get a file;

// Upload the file to the path "folderName/file.jpg"
let uploadTask = storageRef.putFile(localFile, metadata: nil)

let observer = uploadTask.observeStatus(.Progress) { snapshot in
  print(snapshot.progress) // NSProgress object
}

Android
StorageReference storageRef = FirebaseStorage.getInstance().reference().child("folderName/file.jpg");
Uri file = Uri.fromFile(new File("path/to/images/file.jpg"));
UploadTask uploadTask = storageRef.putFile(file);
uploadTask.addOnProgressListener(new OnProgressListener() {
    @Override
    public void onProgress(UploadTask.TaskSnapshot snapshot) {
        System.out.println(snapshot.getBytesTransferred().toString());
    }
});


進捗のリスナーがアップロードのスナップショットを返し、ファイルがサーバーにアップロードされます。このスナップショットから、ファイルの合計サイズ(バイト数)や現時点でアップロードされているバイト数などの有用な情報を得ることができ、アップロード済みの比率の計算やアプリの UI コントロールのアップデートを行うこともできます。

4. メソッド 1 つでファイルをダウンロード

Firebase Storage では、2 つの方法でファイルをダウンロードできます。1 つ目は SDK のリファレンスを使用する方法、もう 1 つはダウンロード URL を使用する方法です。iOS および Android ユーザーは、ファイルをメモリやディスクにダウンロードしたり、ダウンロード URL からダウンロードすることができます。ウェブ SDK では、ダウンロード URL からファイルをダウンロードできます。

ウェブ
var storageRef = firebase.storage.ref("folderName/file.jpg");
storageRef.getDownloadURL().then(function(url) {
  console.log(url);
});

iOS
let storageRef = FIRStorage.reference().child("folderName/file.jpg");
storageRef.downloadURLWithCompletion { (URL, error) -> Void in
  if (error != nil) {
    // Handle any errors
  } else {
    // Get the download URL for 'images/stars.jpg'
  }
}

Android
StorageReference storageRef = FirebaseStorage.getInstance().reference().child("folderName/file.jpg");
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener() {
    @Override
    public void onSuccess(Uri uri) {
        // Got the download URL for 'users/me/profile.png'
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});


iOS と Android のアプリでは、メモリまたはディスクにファイルを格納できます。また、URL を使って一般的な画像キャッシュ ライブラリと連携させることもできます。ウェブ アプリでは、モダンブラウザが持っている強力なキャッシュ システムを活用できるため、URL を使う方式が好まれる場合があります。

5. ストレージ セキュリティ ルールによるユーザーベースのセキュリティ

Realtime Database と同様に、Firebase Storage でもアップロードできるファイルのサイズやタイプを制限したり、誰がどのファイルにアクセスできるかを指定するためのルールが提供されます。Firebase Storage は Firebase Authentication と一体になっているので、アプリケーション内のユーザーに対してファイルを保護することができます。この機能は、ユーザーのプロフィール写真のアップロード権限をそのユーザーだけに与える一方、そのプロフィール写真を誰でも閲覧できるようにしたい場合などに便利です。

// Only a user can upload their profile picture, but anyone can view it
service firebase.storage {
  match /b//o {
    match /users/{userId}/profilePicture.png {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}


ご意見をお寄せください。

私たちは、Firebase Storage で実現してきたことに誇りを持っています。しかし、この機能はまだスタートしたばかりです。皆様のフィードバックをお待ちしています。Firebase Storage を活用するためのヒントをお持ちでしょうか。Firebase Storage を利用する目的は何ですか。アプリの開発に役立ちそうな機能はありますか。ぜひ、コメントを残すか、Slack のチーム経由でご意見をお寄せくください。


Posted by Khanh LeViet - Developer Relations Team