33
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firebase Storage から getDownloadURL を使わずに(少し早く)ダウンロードする

Last updated at Posted at 2020-06-25

Firebase Storage でパーマネントリンクを発行する方法を紹介します。

Firebase Storage とセキュリティルール

Firebase Storage は大容量のデータを保存することのできるストレージです。画像ファイルや、比較的大きな (例えば数 MB もあるような) JSOM などを保存したい場合は、Firestore ではなく Firebase Storage を使うと思います。

Firebase Storage のサンプルコードを読むと、 getDownloadURL というメソッドが登場します。

const ref = firebase.storage().ref('images/stars.jpg'); // 1. 準備
const url = await ref.getDownloadURL(); // 2. ダウンロード URL を取得する
const response = await fetch(url);      // 3. URL からダウンロードして、レスポンスを得る
const image = await response.blob();    // 4. レスポンスからバイナリを得る

上記は公式サンプルコードではなく、オリジナルです。

2. ダウンロード URL を取得する の箇所で getDownloadURL が使われています。ここで注目して欲しいのは、この関数の戻り値が非同期であることです。ただ URL を得るだけの関数がなぜ非同期なのかというと、この操作が実際には "秘密の URL を取得するために Google のサーバで認証を行っている" からです。

ここでいう認証とは、 storage.rules ファイルによって定義されたセキュリティルールに合致するかどうかの判定です。このファイルは Firebase プロジェクトを作ったときに作られているかも知れませんが、なければウェブ上のダッシュボードからも読み書きできます。

さて、この認証は場合によっては "お節介" かも知れません。僕の手元では 500ms-700ms ほどの時間がかかっていますが、ネットワークが遅い場合はもっとかかることもあるでしょう。とにかくダウンロード時間を短縮したい場合 (ユーザーを待たせたくない場合)、この操作をスキップすることができます。

ただし、 この操作はバケット全体に影響を与えます。 認証をスキップするということは、誰もがストレージオブジェクトをダウンロード可能になってしまうということです。それでも問題ない場合は、以下の手順を試す価値があります。あるいは、新しいバケットを作って、ダウンロードされて大丈夫なものだけをまとめることもできます。いずれにせよ、ダウンロードされて困るものがひとつでもバケットに入っている場合は、この方法を使うべきではありません。

ファイルごとにパーマネントリンクを発行したい場合は firebase-admin の Storage オブジェクトから利用可能な getSignedUrl に目一杯長い期間を設定します。詳細は割愛します。

Firebase Storage バケットを公開する

デフォルトでは、 Firebase Storage のダウンロード URL はすべて "秘密の URL" です。これがどこで決められているかというと、 IAM で決められています。

IAM を変更するには、ブラウザで ストレージブラウザ を開いて、 Firebase プロジェクトと同じ名前のプロジェクトを選択したら、一覧から (Firebase のプロジェクト名).appspot.com という名前のバケットを開いてください。(おそらく出てくると思いますが、Firebase 側で設定が必要かも知れません)

ストレージブラウザでは "Google Cloud Storage" と呼ばれていますが、これは "Firebase Storage" のことだと読み替えてください。

権限タブに移動すると、IAM を表示したり変更したりできます。メンバー追加をクリックして、 allUsers に対して Storage レガシーバケット閲覧者 ロールを設定してください。このロールは標準で存在する中では唯一 storage.objects.get 権限だけを含んでいます。権限については公式のドキュメントに詳しい説明があります。

↑こちらの説明は間違っており、正しくは Storage レガシー オブジェクト読み取り でした。

Image from Gyazo

保存ボタンを押すと、バケットが誰からもダウンロード可能になります。試しに、適当なオブジェクトをダウンロードしてみましょう。 インターネットに公開 🔗 というボタンをクリックすると、パーマネントリンクを開いてくれます。(オブジェクトのヘッダによっては直接ダウンロードされることもあります)

Image from Gyazo

パーマネントリンクは https://storage.googleapis.com/(Firebase プロジェクトの名前)/(オブジェクトのパス) という URL になっています。この URL を fetch() なりすれば、 getDownloadURL を使わずにダウンロードすることができます。

33
25
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?