AWS S3 から Cloud Storage for Firebase にファイルをコピー
はじめに
AWS S3 のオブジェクト群を Firebase の Storage (Cloud Storage for Firebase) にコピーする方法。
TL;DR
- 公式手順(参考1, 参考2)があるので、要件を満たせるならそれを使う
- 公式手順でダメな場合は自分でスクリプトを組む
- Node.js の場合は
aws-sdk
(aws/aws-sdk-js) とfirebase-admin
(firebase/firebase-admin-node) を使う - 1ファイルをコピーするサンプルコード作った
- Node.js の場合は
- 目的の 公式ドキュメント(API リファレンス)にたどり着く追うのが割と大変
目次
環境・条件
1 | $ sw_vers |
詳細
公式手順
「どこかのタイミングで1回コピー」や「毎日1回コピー」で良ければ公式手順がある。
以下も参考になるかも。
今回やりたいこと
今回やりたいことは以下。前述の公式手順では要件を満たせないため自分で Node.js でスクリプトを作成した。
- S3 から Storage に定期的(1時間に1回など、1日より短いスパン)にコピー
- コピー先の格納パスを変更したい(S3 で
/a/b/c.png
だったものを Storage では/x/y/c.png
に置きたい)
セットアップ
パッケージインストール
npm i
で aws-sdk
(aws/aws-sdk-js) と firebase-admin
(firebase/firebase-admin-node) をインストール。
1 | $ npm i aws-sdk firebase-admin |
Firebase Admin SDK 秘密鍵生成
Firebase web console → プロジェクト選択 → プロジェクトを設定 → サービスアカウント → Firebase Admin SDK → 新しい秘密鍵の生成
ダウンロードしたファイルを、スクリプトと同じディレクトリに配置。(xxxx-adminsdk-xxxx.json
)
AWS IAM アクセスキー生成
AWS Console → IAM → ユーザー → 認証情報 → アクセスキーの生成
CSV ファイルをダウンロードしたら、スクリプトと同じディレクトリに JSON ファイルを作成。(今回は aws.config.json
とした)
1 | { |
サンプルコード
S3 から 1ファイル取得して、Storage にアップロードするサンプル。例外処理とかちゃんとやってないので注意。
複数ファイルを処理したい場合は、listObjects
と組み合わせればいけるはず。
1 | const AWS = require('aws-sdk'); |
簡単な解説
コード読めばわかるけどやってることは以下。
- AWS S3 を扱うための設定
- Firebase Admin(Storage for Firebase) を扱うための設定
- S3 からオブジェクト取得
- いったんローカルに保存
- 保存したファイルを Storage にアップロード
もう少しちゃんとやるとしたら、以下あたりの処理追加や考慮が必要。
listObjects
で複数ファイルのパスを取得して処理MaxKeys
とMarker
オプションを使ったページング処理が必要
- Storage にアップロード成功したローカルファイルの削除
- Storage にアップロード失敗したファイルの情報保持
- 処理が途中で落ちた場合に再開できるような情報(例: アップロード成功した最新ファイル名など)の保持
- 毎回
await
すると効率が悪い(と思う)ので、非同期で処理listObjects
で100件取ってきたら、100件分は一気にダウンロード(getObject
)して、すべてアップロードできたら次100件にいく、とか
- 例外処理全般
使用しているメソッドなど
コード中にもコメントでリンクを書いているが簡単に整理(一部は API doc にたどり着くのに苦労したので。。。
AWS.config.loadFromPath
new AWS.S3
s3.listBuckets
s3.listObjects
s3.getObject
path.dirname
fs.mkdirSync
fs.writeFileSync
admin.initializeApp
admin.storage.bucket
bucket.upload
その他・メモ
苦労した点
AWS も Firebase も公式ガイドがある、のは良いんだけど突っ込んだ事をやろうと思った時に、情報の繋がりがなかったり firebase-admin
ではなく firebase
(firebase/firebase-js-sdk) の例だったりで調べるのに苦労した。
ウェブでファイルをアップロードする | Firebase にアップロード方法が書かれているが、前述の通り firebase
のサンプルなので Node.js 環境だと使えなかったりする。
また、Storage | Admin Node.js SDK | Firebase をちゃんと見るとわかるが、Bucket 取得したらその後は firebase-admin
ではなく @google-cloud/storage (googleapis/nodejs-storage)
側のドキュメントを見る必要があったりする。(なので、Admin Node.js SDK 側でアップロードするメソッドを探しても見つからない)
まとめ
- 公式手順(参考1, 参考2)があるので、要件を満たせるならそれを使う
- 公式手順でダメな場合は自分でスクリプトを組む
- Node.js の場合は
aws-sdk
(aws/aws-sdk-js) とfirebase-admin
(firebase/firebase-admin-node) を使う - 1ファイルをコピーするサンプルコード作った
- Node.js の場合は
- 目的の 公式ドキュメント(API リファレンス)にたどり着く追うのが割と大変
参考文献
- JSON ファイルから認証情報を Node.js にロードする - AWS SDK for JavaScript
- Amazon S3 バケットの作成と使用 - AWS SDK for JavaScript
- Class: AWS.S3 — AWS SDK for JavaScript
- aws/aws-sdk-js: AWS SDK for JavaScript in the browser and Node.js
- サーバーに Firebase Admin SDK を追加する
- Google Cloud Storage: Node.js Client - Documentation
- Admin Node.js SDK | Firebase
- firebase/firebase-admin-node: Firebase Admin Node.js SDK
- googleapis/nodejs-storage: Node.js client for Google Cloud Storage: unified object storage for developers and enterprises, from live data serving to data analytics/ML to data archiving.
関連記事
- AWS lambda で S3 の画像をリサイズする(チュートリアル)
- docker-lambda + sharp で画像変換する AWS Lambda Function
- axios で添付ファイルありのリクエスト(multipart/form-data の POST)
- AWS S3 バケットをリネーム(できないので別バケットにコピー)
- Chart.js(vue-chartjs) でツールチップの表示内容を変更
- Vue.js で日本語変換での誤発火を抑止しつつ Enter キーで Submit
- JavaScript で URL のクエリパラメータを操作する方法
- jQuery Select2 で、初期値の設定と選択状態のクリア