基本は公式の手順に従うまでですが、ところどころ躓いたのでメモ。
公式の手順
手動バックアップ
https://firebase.google.com/docs/firestore/manage-data/export-import?hl=ja
自動バックアップ
https://firebase.google.com/docs/firestore/solutions/schedule-export?hl=ja
バケットの作成方法
上記どちらを行う場合も、まず先にバケットを作る必要がありますが以下を参考に作成しました。
https://nipo.sndbox.jp/develop-blog/firestore-backup
StorageはGCP管理画面の左メニューのプロダクト>ストレージの中にあります。
私はバケットの名前は [PROJECT_ID]-exportとしました。
ローカルにファイル一式をinitする
Cloud Functions のソースファイルを入れるフォルダを作る。私は/Users/takuya/Development/[PROJECT_NAME]-functions
という階層・名前で作成しました。最初に箱を作らないとinitしたときに今いる場所に色んなルールファイルなどができちゃいます。
$ cd [PROJECT_NAME]-functions # さっき作ったフォルダに移動
$ firebase init functions --project PROJECT_ID
# PROJECT_ID は小文字
JavaScriptかTypeScriptを選ぶように言われますが、公式の手順ではJavascriptを選択(ただし凄い人たちはCloud FunctionsではTypeScriptを使うことを勧めている人が多い印象)。
ESLintを使うか聞かれデフォルトではN
(すなわちNo)となってますが私は入れました。コードのバグを見つけてくれるものでありTypeScriptだとデフォルトY
なので、コンパイルが不要なJavaScriptではいらない(VSCodeなどのエディタで警告してくれるから)のかな?
index.jsを編集
ここを編集せずにデプロイするとエラーになるので編集後にデプロイするように。
またバックアップ時間は私は unix-cron 文字列形式(* * * * *)
で記述しました。
https://cloud.google.com/scheduler/docs/images/schedule-fields.png?hl=ja
アメリカ時間であることに注意。
また Node.js 10 からはprocess.env.GCP_PROJECT
の一文を追加しないとCannot read property 'toString' of undefined
というエラーが出てしまうのも公式には記述無く。
const functions = require("firebase-functions");
const firestore = require("@google-cloud/firestore");
const client = new firestore.v1.FirestoreAdminClient();
// Replace BUCKET_NAME
const bucket = "gs://バケット名";
exports.scheduledFirestoreExport = functions.pubsub
.schedule("45 19 * * *") // 好きな時間帯:私は19:45(日本時間2:45)にしました
.onRun((context) => {
const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT; // 公式のコードに追加追加
const databaseName = client.databasePath(projectId, "(default)");
return client
.exportDocuments({
name: databaseName,
outputUriPrefix: bucket,
// Leave collectionIds empty to export all collections
// or set to a list of collection IDs to export,
// collectionIds: ['users', 'posts']
collectionIds: [],
})
.then((responses) => {
const response = responses[0];
console.log(`Operation Name: ${response["name"]}`);
return response;
})
.catch((err) => {
console.error(err);
throw new Error("Export operation failed");
});
});
Cloud Functions をデプロイ
$ firebase deploy --only functions
--only functions
を付けないと既存のFireStoreやRealtime Databaseなどが上書きされてしまうはずなので注意!
Cloud Scheduler の場所
公式のリンクでは変なトップ画面に飛ばされる。
まず「APIとサービス」で「Cloud Scheduler」を検索して追加する。
追加後のダッシュボードでは利用状況や認証情報などしか見れずここでは実行できない。
ホームに戻り左側メニューの下の方にスクロールすると「Cloud Scheduler」があるのでクリックするとここにジョブができているはず。今すぐ実行
ボタンが見つかる。
下記のようにピン留めしておくと上の方に「Cloud Scheduler」が来て以後使いやすい。
あとは公式通りの手順で問題なく行けました。