Help us understand the problem. What is going on with this article?

Firebase Cloud Storageに格納した画像を一覧表示する

More than 1 year has passed since last update.

はじめに

まずはじめに、ここで記述する方法が正攻法なのかわからないので、もっといい方法があれば教えてほしいという意味も込めて投稿しています。

問題点

最近Firebaseをさわり始めました。

Cloud Storageを使っていた際、「Cloud Storage上の特定のフォルダ内に置かれている画像を一括で取得して一覧表示させたい」ということがあった。

単純にCloud Storageに格納されているとある画像を表示させようと思ったら、下記のようにして、
1. Cloud Storage 参照を作成
2. getDownloadURL()でファイルのダウンロードURLを取得
3. <img>srcに突っ込む
という手順を取ってやればいい。

ref = firebase.storage().ref().child('img/sample.jpg');
ref.getDownloadURL().then((url) => {
  document.getElementById('image').src = url;
});

しかし残念ながら、 Cloud Storage上の特定のフォルダ内に置かれているファイルのダウンロードURLを一括で取得するようなAPIは提供されていない...

解決策

方針としては、Cloud FunctionsとFirestoreを使用します。
1. Cloud Storage上に画像をアップロード
2. Cloud Functions経由でFirestoreに画像のパス、もしくはダウンロードURLを書き込む
3. クライアントサイドからFirestoreに格納された情報からダウンロードURLを取得し、表示する

Cloud Functions

Cloud Functions for Firebase を使用すると、Firebase 機能や HTTPS リクエストによってトリガーされたイベントに応じて、バックエンド コードを自動的に実行できます。

今回はCloud Storage上にアップロードされたタイミングでCloud Functionsを実行しFirestore内に必要な情報を書き込むようにします。

Firestore

Google の柔軟でスケーラブルな NoSQL クラウド データベースを使用して、クライアント側開発とサーバー側開発のデータを保存、同期します。

データベースみたいなもので、ここへCloud Functionsから必要な情報を書き込んでいきます。

実装

とりあえずコード全体

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

exports.writeUrl = functions.storage.object().onFinalize((object) => {
  const bucketName = 'hoge.appspot.com'; // ご自身の
  const filePath = object.name;
  const db = admin.firestore();

  db.collection('images').add({
    filePath,
    downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media`,
  }).then(() => console.log('Done')); // eslint-disable-line no-console
});

Cloud Functionsで使う関数を定義していいます。
onFinalize()内で、ファイルのアップロードされたときの処理を記述します。
object.nameでファイルへのパスが取得できるので、これをFirestoreに書き込みます。
または、https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media
で、Cloud Storage上のpublicなファイルのURLが取得できるので(Firebaseの小ネタ集 - Qiita)、これをFirestoreに書き込みます。

あとは一覧表示したいときに、Firestoreの(上記の例では)imagesコレクションを取得してきて、ドキュメント分ループさせて、はじめに記述したようにfilePathからダウンロードURLを取得して一覧表示させます。
downloadUrlを使えばgetDownloadURL()する必要がないのでもっと楽だと思います。

所感

これが正攻法なのかは分からないです...
Cloud Storageの画像を一覧表示するときは普通どうするものなのだろうか...

musatarosu
最近はiOSがメインです。 JavaScript / React / Firebase も少しやっています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした