LoginSignup
3

More than 3 years have passed since last update.

Firebase firestoreのバックアップをCloudFunctionsで自動実行してみた

Last updated at Posted at 2019-12-24

はじめに

atma(あーとま)Advent Calendar 2019 25日目担当のこーたです。
今回はFirestoreを触った知見を共有したいと思います。

前提

Firestoreには自動バックアップ機能がありません。 <-これが結構痛い
そこでFirestore exportのAPIをCloud FunctionsのCloud Pub/Subで定期的に叩いてみました。

結論

簡単に実装出来ました。

index.js
const functions = require("firebase-functions");
// 初期化
const admin = require("firebase-admin");
admin.initializeApp();
// 東京リージョンでデプロイ
const FIREBASE_REGION = "asia-northeast1";
const rp = require("request-promise");
const { google } = require('googleapis');
/**
 * Firebase Cloud Firestoreのバックアップ処理
 */
exports.backupFirestoreData = functions
  .region(FIREBASE_REGION)       
  .pubsub.schedule('0 3 * * *')  //ここで実行隔離を指定
  .timeZone("Asia/Tokyo")       
  .onRun((context) => {
    const projectId = 'projectId'
    const scopes = ['https://www.googleapis.com/auth/datastore', 'https://www.googleapis.com/auth/cloud-platform']
    const key = require(`./${projectId}.json`)  //jsonからGCSへのアクセス権を読み込み
    const url = `https://firestore.googleapis.com/v1beta1/projects/${projectId}/databases/(default):exportDocuments`
    const jwtClient = new google.auth.JWT(
      key.client_email,
      key.private_key,
      scopes,
    )
    jwtClient.authorize().then((credentials) => {
      //日付を取得
      require('date-utils');
      const date = new Date();
      date.setTime(date.getTime() + 1000 * 60 * 60 * 9); // JSTに変換
      const formatted = date.toFormat("YYYY_MM_DD_HH24_MI_SS");
      rp.post(url, {
        headers: { Authorization: `Bearer ${credentials.access_token}` },
        json: true,
        body: { outputUriPrefix: `gs://projectId.appspot.com/backup/${formatted}` }
      })
    });
    return null;
  })

必要パッケージ

Date 型を扱いやすくするdate-utilsを使っているのでインストールして下さい。

$ npm install date-utils

or

$ yarn add date-utils

解説

Firestore exportのAPIをCloud FunctionsのCloud Pub/Subで定期的に叩いています。

スクリーンショット 2019-12-24 16.54.25.png

サービスアカウントとは

サービス アカウントは、個々のエンドユーザーではなく、アプリケーションや仮想マシン(VM)に属している特別な Google アカウントです。アプリケーションはサービス アカウントを使用して、ユーザーの関与を必要とせずに Google のサービス API を呼び出すことができます。

  const key = require(`./${projectId}.json`)  //jsonからGCSへのアクセス権を読み込み

この部分でサービスアカウントキーを読み込んでいます。

バックアップ先

Firebase Cloud Storageのアドレスを指定しています。

  body: { outputUriPrefix: `gs://projectId.appspot.com/backup/${formatted}` }

バックアップしたものはこのような感じで保存されます。
スクリーンショット 2019-12-24 16.55.14.png

※projectIdは本来envに記載するべき内容ですが、分かりやすいようにコードに記載しています。

最後に

上記コードではサービスアカウントキーのjsonを渡しています。

その他にApplication Default Credentialsという仕組みがあるみたいです。
https://cloud.google.com/docs/authentication/production?hl=ja
この仕組みを使えばサービスアカウントキーのjsonを渡さずに実装することが可能かもしれません。
次に触る機会がありましたら、この方法での実装も試してみたいです。

以上
Firebase firestoreのバックアップをCloudFunctionsで自動実行してみたでした!

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
3