LoginSignup
29
27

More than 3 years have passed since last update.

Cloud Functionsなどfirebase-adminでStorageを追加や削除・存在確認をする

Last updated at Posted at 2019-08-20

開発中の積読用の読書管理サービス「積読ハウマッチ」で、
新しく報告機能をリリースしました:tada:

画面はこんな感じ。

ツイートにも書いてあるとおり、裏では、

  1. OGP画像が生成しているかの存在確認
  2. 生成してなければ、OGP画像の生成

をしています。

Firebase Functions上でこれらの処理をしているのですが、
firebase-adminを使った場合、Storageの扱いが違ったので、
備忘録的にまとめておきます。

(ImageMagicを使った画像生成とアップロードの記事はこちら)

firebase-adminではGoogle Cloud StorageのAPIが使われる

@hitsuji-hanetaさんの記事をみると、クライアント版とは違い、
firebase-adminを使うと、Google Cloud StorageのAPIが使わるよう。

なので、APIリファレンスとかも、
@google-cloud/storageのほうを確認する必要がある。

いろいろやってるコード

コードとしては、こんな感じ。

  1. ファイルの追加/アップロード: upload()
  2. ダウンロードURLの取得: download()
  3. ファイルの存在確認: exists()
  4. ファイルの削除: deleteFile()

で上記の処理をそれぞれおこなっています。

firebase-adminをローカルでも実行できるので、
今回はFunctionsではなく、そちらのコード例。

const admin = require("firebase-admin");

// 配置したサービスアカウントの秘密鍵を取得
const serviceAccount = require("./key/XXXXX.json");

// firebase-adminを初期化
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  // storageBucketはローカルで実行するときのみ必要。
  // Functions上ではFunctions側で設定される
  storageBucket: "your-storage-bucket-name.appspot.com"
});

// storageのbucketのインスタンスを取得
const bucket = admin.storage().bucket();

/**
 * Cloud Storageへのアップロード
 *
 * @param {string} uploadFile アップロードするファイル
 * @param {string} uploadPath アップロード先のStorageのパス
 */
async function upload(uploadFile, uploadPath) {
  await bucket.upload(uploadFile, { destination: uploadPath });
}

/**
 * Cloud Storageへのダウンロード(StoregeのURL取得)
 * 簡易化のため、署名付きURLの取得ではなく、Storage上のURLを生成しています。
 * 
 * @param {string} uploadedPath アップロード済みのstorage上のパス
 * @returns {string} ダウンロードURL
 */
async function download(uploadedPath) {
  const STORAGE_ROOT = "https://firebasestorage.googleapis.com/v0/b";
  const bucketName = bucket.name;
  const dlPath = encodeURIComponent(uploadedPath);
  const dlURL = `${STORAGE_ROOT}/${bucketName}/o/${dlPath}?alt=media`;

  return dlURL;
}

/**
 * Cloud Storage上のファイルの存在確認
 *
 * @param {string} uploadedPath アップロード済みのstorage上のパス
 * @returns {boolean} ファイルの存在有無
 */
async function exists(uploadedPath) {
  const exists = await bucket.file(uploadedPath).exists();
  return exists[0];
}

/**
 * Cloud Storage上のファイルの削除
 *
 * @param {string} uploadedPath アップロード済みのstorage上のパス
 */
async function deleteFile(uploadedPath) {
  await bucket.file(uploadedPath).delete();
}

// ****************************
// * MAIN
// ****************************
async function main() {
  console.log(`***** START MAIN`);

  // アップロード
  const uploadFile = "./ogp_top.png"; // アップロードしたいファイルのパス
  const uploadPath = "ogp/generate_ogp.png"; // アップロード先のStorage上のパス
  await upload(uploadFile, uploadPath);
  console.info(`${uploadFile} is uploaded into '${uploadPath}'.`);

  // ダウンロード
  const uploadedPath = uploadPath;
  const downloadURL = await download(uploadedPath);
  console.info(`downloadURL=${downloadURL}`);

  // ファイルの存在確認
  const isExists = await exists(uploadedPath);
  console.info(`isExists=${isExists}`);

  // ファイルの削除
  await deleteFile(uploadedPath);
  console.info(`${uploadedPath} is deleted.`);

  console.log(`***** END   MAIN`);
}

main().then();

ローカルで実行するときの注意点としては、admin.initializeApp()時に
storageBucketを設定しないといけないこと。
Functions上で実行する場合は、Functions側で設定してくれるので不要です。

// firebase-adminを初期化
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  // storageBucketはローカルで実行するときのみ必要。
  // Functions上ではFunctions側で設定される
  storageBucket: "your-storage-bucket-name.appspot.com"
});

これで、ローカルで生成したファイルもアップロードできたりします(´ω`)
もちろん、Cloud Functionsでも動くので、冒頭のツイート動画のように、
存在確認&生成などもできたりヽ(=´▽`=)ノ

おわりに

Nuxt.jsやFirebaseを使いながら、機能追加してるサービスです!
積読総額ランキングや人気の本などもあるので、よかったらあそんでもらえれば!!

積んでる本の総額がわかる読書管理サービス
積読ハウマッチ

要望・感想・アドバイスなどあれば、
公式アカウント(@MemoryLoverz)や開発者(@kira_puka)まで〜♪

参考にしたサイト

29
27
4

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
29
27