今回は、Cloud Storage For Firebase(以後、長いのでFirebase Storageと呼びます)にNode.jsアプリケーションからのファイル操作方法についてまとめていきます。
公式ドキュメントを参考に実装すればあまり迷うことはありませんが、自身の備忘録としてまとめていきますので、参考程度に見ていただければと思います。
また、Cloud Funtions for Firebaseにデプロイする方法についても、以前記事にまとめていますので良かったら参考にしてください。
Firebaseについて
Firebaseは、Googleが提供するモバイルアプリおよびWebアプリケーションの開発プラットフォームです。いわゆるBaaS(Backend as a Service)の代表的な一つで、バックエンドの機能を提供してくれるサービスとも言えます。開発者はFirebaseを使用して、リアルタイムデータベース、認証、ストレージ、ホスティング、クラウド関数などの機能を簡単に統合することができます。Firebaseはクラウドベースのサービスであり、スケーラビリティに優れ、セキュリティと信頼性が高いのが特徴です。また、シンプルなAPIと直感的なダッシュボードを提供するため、開発者は迅速にアプリケーションを構築・展開・運用できます。
Cloud Storage for Firebaseについて
概要
Cloud Storage for Firebase は、Google の基準や規模をもとに構築された、強力かつシンプルでコスト効果の高いオブジェクト ストレージ サービスです。Cloud Storage 用の Firebase SDK では、ネットワーク品質にかかわらず、Firebase アプリでのファイルのアップロードとダウンロードに Google のセキュリティが適用されます。
このクライアント SDK は、画像、音声、動画、またはその他のユーザーが生成したコンテンツを格納する場合に使用できます。使用されるサーバーでは、Firebase Admin SDK を使用してバケットを管理し、ダウンロード URL を作成できます。また、Google Cloud Storage API を使用してファイルにアクセスできます。
https://firebase.google.com/docs/storage?hl=ja
サービス自体はAWS S3と似たようなサービスであり、GCP上のCloud Storageよりはシンプルになっているイメージ
特徴
- 堅牢なオペレーション
Cloud Storage for Firebaseはネットワークの品質に影響されず、アップロードとダウンロードが安全で柔軟に行えます。途中で中断されても再開可能なため、効率的なデータ処理が可能です。 - 強固なセキュリティ
Firebaseの認証機能と統合されたCloud Storage for Firebaseは、シンプルで直感的な認証を提供します。Googleのセキュリティモデルを活用し、ファイルのアクセスを細かく制御できます。 - 高いスケーラビリティ
Cloud Storageはエクサバイト規模に対応し、急激なアプリの成長に対応します。SpotifyやGoogleフォトと同じインフラストラクチャを使用することで、スムーズなアプリの拡大が可能です。
実装の流れ
開発環境
- Node.js:
v18.15.0
- npm:
v9.5.0
- TypeScript:
v5.1.6
- OS:
MacOS Monterey
構築手順
基本的な進め方については下記ドキュメントを参考にしていますので、詳細が気になる方は参照してください。
また、具体的なファイルの操作方法について参照したい場合は、「ファイル操作の実装」だけを見て頂ければと思います。
Firebaseプロジェクトのセットアップ
まずはFirebase上でプロジェクトを作成しない限りは前に進めないため、下記を参考にプロジェクトを作成する。
すでに作成済みの場合は、このステップは不要となる。
ローカルに実行環境構築
実行環境の準備
今回は、Functionsの時のように初期化等は不要なので、適当なNode.js & TypeScriptの土台となるアプリケーションを構築します。以下の参考記事を載せておきます。
Firebase Admin SDKのパッケージをインストール
$ npm install --save firebase-admin
Firebaseプラットフォームをバックエンドで使用する際に利用される公式の開発キットです。このSDKを使用することで、サーバーサイドの環境(Node.jsなど)からFirebaseプロジェクトにアクセスし、データベースへの書き込みや認証、クラウド機能の実行などFirebaseの機能を利用できる。
今回は、Storageに対してバケット取得やファイル操作のために利用する。
認証情報(JSON)の取得
ここからが本題です。
まずはStorageと疎通するための認証情報を取得します。
コンソール上で秘密鍵のダウンロード
- Firebaseコンソールにアクセスし、作成したプロジェクトに移動する
- 歯車マークから「プロジェクトの設定」をクリックし、「サービスアカウント」タブへ移動(画像参考)
- 「新しい秘密鍵の生成」ボタンをクリックする
- 表示内容を確認し、「キーを生成」ボタンをクリックする
- ダウンロードが終われば完了
秘密鍵を特定場所へ移動
秘密鍵関連は.ssh配下に置いているので移動させますが、参照できればどこでもOK
$ mv sample-project-xxxxxxx-xxxxxx.json ~/.ssh/
Firebase Admin SDK の初期化
この時点での完成系はこちら
import { cert, initializeApp } from 'firebase-admin/app';
import { load } from 'ts-dotenv';
const env = load({
FIREBASE_CREDENTIALS: String,
STORAGE_BUCKET: String,
});
initializeApp({
credential: cert(env.FIREBASE_CREDENTIALS),
storageBucket: env.STORAGE_BUCKET,
});
const bucket = getStorage().bucket();
Firebase Admin SDK の各種サービスを使うためには、initializeApp
メソッドを呼び出してインスタンス化しておく必要があり、その際に必要なのが先ほどのダウンロードした認証情報(JSON)となる。
そのため、今回は環境変数にFIREBASE_CREDENTIALS
として格納し、併せてバケット情報をSTORAGE_BUCKET
としてセットする。
FIREBASE_MYAPP_CREDENTIALS=/Users/username/.ssh/sample-project-xxxxxx-xxxxxx.json
STORAGE_BUCKET=sample-project-xxxxxx.appspot.com
ファイル操作の実装
バケット取得からローカルファイルをStorageへアップロードするコードが以下
import { cert, initializeApp } from 'firebase-admin/app';
import { getDownloadURL, getStorage } from 'firebase-admin/storage';
import { load } from 'ts-dotenv';
import * as path from 'path';
const env = load({
FIREBASE_MYAPP_CREDENTIALS: String,
STORAGE_BUCKET: String,
});
initializeApp({
credential: cert(env.FIREBASE_MYAPP_CREDENTIALS),
storageBucket: env.STORAGE_BUCKET,
});
const bucket = getStorage().bucket();
(async () => {
const filePath = path.join(__dirname, '..', 'tmp', 'sample.json');
const destFileName = 'sample/sample-v1.json';
await bucket.upload(filePath, { destination: destFileName });
})();
ファイル操作処理の一覧
ここからはよく使用するであろうファイル操作のメソッドとその使い方を紹介します。
とはいえ、公式ドキュメントに詳しく書いてあり、今回紹介するメソッド以外にもたくさんあるので、詳しくは参照してください。
ファイルのアップロード
await bucket.upload(filePath, { destination: destFileName });
ファイルのダウンロード
await bucket.file(fileName).download({ destination: destFileName });
ファイルの削除
await bucket.file(fileName).delete();
ファイルのダウンロードURL取得
const fileRef = bucket.file(fileName);
const downloadUrl = await getDownloadURL(fileRef);
ファイルの一覧取得
const [files] = await bucket.getFiles();
files.forEach((file) => console.log(file.name))
ファイルのメタデータ取得
await bucket.file(fileName).getMetadata();
ファイルのコピー
const destFileName = 'sample-copy/sample.json';
await bucket.file(fileName).copy(destFileName);
ファイルの移動
const destFileName = 'sample-move/sample.json';
await bucket.file(fileName).move(destFileName);
ファイルを一括ダウンロード
const [files] = await bucket.getFiles();
files.forEach((file) => {
const parts = file.name.split('/'); //スラッシュ区切りのため
const fileName = parts[parts.length - 1]; //ファイル名のみを取得
const destFileName = path.join(__dirname, '..', 'tmp', fileName);
file.download({ destination: destFileName });
});
まとめ
改めて今回はCloud Storage fo Firebase へのファイル操作方法についてまとめてみました。ドキュメントも充実していましたので、そこまで迷うことなく実装できました。ファイル操作の実装はどこでも使えますし、AWS S3でも似たようなメソッドが用意されているので親近感がありました。
一応過去にまとめた記事も載せておきますので、よかったら見てください。
ここまでご覧いただきありがとうございました。