見出し画像

FireStore(データベース)バックアップ

ソシャゲ(ガチャゲー)では、データベースにMySQLやMariaDB等がよく使われます。CWでも以前はPHP(サーバープログラム)とMySQL(データベース)の組み合わせでソシャゲを作っていました。

データベースは基本毎日深夜とかにバックアップをとってる場合が多いと思われます。保険の面が強いですが、万が一事故が起こりユーザーのデータが消滅してしまうと大変な事になります。いざというときの為にバックアップは重要です。

CWでは、現在はFireBaseを使いCloudFunctions(サーバープログラム)とFireStore(データベース)の組み合わせでソシャゲを作ってますが、当然同じように毎日データベースのバックアップを行います。

PHPとMySQLの組み合わせのときは、Cronという仕組みで定期実行を行いますが、FireBaseの場合も同じような仕組みがあります。しかしFirebaseのサービスの中でもCloudFunctionsとFireStoreは、GCP(Google Cloud Platform)のシステムでありFireBaseはGCPを使っています。

この為Cronではなく、GCPのCloud Schedulerを使ってバックアップをとる事ができます。ここでは、そのやり方を見ていきます。

まずは、GCPコンソールにいき、サービスアカウントを作ります。
GCPコンソールには、ブラウザで直接GCPコンソールに行く方法もあるのですが、ここではFireBaseのコンソール画面のプロジェクト概要の右にある設定ボタンを押し表示された中から「プロジェクトを設定」を選びます。

画像1

「サービスアカウント」を選択すると、表示されたページの右上に「サービス アカウント権限の管理」というリンクがあるので、そのリンク先に飛びましょう。

画像2

GCPコンソールの「IAMと管理」の画面に遷移しますが
左側に並んでるメニューから「サービスアカウント」を選択し「+サービスアカウントを作成」を選択します。

画像3

アカウント名は「backup」としました。

画像4

次にロールを割り当てます。
Cloud Datastore インポート / エクスポート管理者
Storage オブジェクト管理者
の2つを割り当てます。

画像5

サービスアカウントが出来上がって一覧に表示されたら、作ったサービスアカウントの右側の「・」が縦に3つ並んでるボタンを押して鍵を作成を選びます。

画像6

鍵は、P12形式かJson形式か選べますが、Json形式を選んでください。
鍵が作られ、ダウンロードされますので、ダウンロードされた鍵は、firebaseプロジェクトのfunctionsフォルダに格納します。

念の為IAM画面に行って、
Cloud Datastore インポート / エクスポート管理者
Storage オブジェクト管理者
の2つがついているのを確認します。

画像7

次は、バックアップ保存先のバケットを作成します。
GCPコンソール左上の「ナビゲーションメニュー」を押します。

画像8

表示されたメニュー群から「ストレージ」を選択し、その中の「Storage」を選んだ中から「ブラウザ」を選びます。

画像9

画面上部の「バケットを作成」を選びます。

画像10

バケットの名前は、プロジェクトID-firestore-backupとしました。
ロケーションは、FireBaseのFireStoreで使ってるリージョンと同じにしなければなりません。
FireStoreを設定するときにリージョンを設定しますが、だいたいの場合は「asia-northeast1(東京)」を選択してる方が多いと思いますが、その場合はロケーションタイプは「Resion」にして「asia-northeast1(東京)」か
「Multi-region」で「asia」を選ぶかになるようです。
ここを間違えると、バックアップは失敗します。今回は「Resion」にして 「asia-northeast1(東京)」にしました。
ストレージクラスは、「Standard」にしました。
詳細設定は、省略で大丈夫です。

画像11

Cloud Functionsのindex.jsにバックアッププログラムを追加します。

// FireStoreバックアップ
require('firebase-functions/lib/logger/compat');//Node10になってからconsole.logを使うときは必要です。
const projectId = JSON.parse(global.process.env.FIREBASE_CONFIG).projectId;
const { google } = require('googleapis');
const rp = require('request-promise');

async function getAccessToken(){
   const scopes = ['https://www.googleapis.com/auth/datastore', 'https://www.googleapis.com/auth/cloud-platform'];

   let serviceAccount = require('./サービスアカウントで鍵作成した.json');
   const jwtClient = new google.auth.JWT(
       serviceAccount.client_email,
       undefined,
       serviceAccount.private_key,
       scopes,
       undefined
   );
   try{
       //成功です。
       const authorization = await jwtClient.authorize();
       return authorization.access_token;
   }catch(err){
       //失敗です。
       return err;
   }
}

async function exportFirestore(){
   try{
       const accessToken = await getAccessToken();
       const endpoint = `https://firestore.googleapis.com/v1beta1/projects/${projectId}/databases/(default):exportDocuments`;
       const option = {
           headers: {
               Authorization: `Bearer ${accessToken}`
           },
           json: true,
           body: {
               outputUriPrefix: `gs://${projectId}-firestore-backup`,
           }
       };
       const res = await rp.post(endpoint, option);
       return res;
   }catch(err){
       console.log(`error occurred when doing backup: ${err}`);
       return err;
   }
}

exports.FirestoreBackup = functions.region('asia-northeast1').pubsub
   .topic('FirestoreBackup')
   .onPublish(async (msg)=>{
       try{
           const res = await exportFirestore();
           console.log(`firestore backup job is successfully registered: ${res}`);
           return res;
       }catch(err){
           console.log(`error occurred when backuping: ${err}`);
       }
   });

「サービスアカウントで鍵作成した.json」の部分は、サービスアカウントで作成したfunctionフォルダに入れたjsonファイルを指定します。

outputUriPrefix: `gs://${projectId}-firestore-backup
の部分は先程バケット作成したバケットを指定します。
FirebaseのプロジェクトID-firestore-backup で名前をつけたのであれば、そのままで大丈夫です。
FunctionsをデプロイしFireBaseコンソール画面でデプロイ出来てる事を確認します。

画像12

次は、いよいよ「Cloud Scheduler」です。
FireBaseコンソールからGCPコンソールに戻ります。
GCPコンソールから「ナビゲーションメニュー」の中から「ツール」から「Cloud Scheduler」を選びます。

画像13

画面上部のジョブを作成を選びます。

画像14

ジョブの作成で名前をつけます。
任意の名前でいいと思いますが、「firestore-backup」としました。

画像15

設定は以下のようにしました。バックアップは深夜3時に行います。

画像16

設定できたら、右側にある「今すぐ実行」ボタンを押して、実行されるか確認します。

画像17

実際実行されてうまくいけば成功と出ますが、念の為ストレージのバケットを見て成功してるかバックアップファイルが出来上がってるか確認します。

画像18

後はバックアップの保管期限を決めます。画面上部のライフサイクルボタンを押します。

画像19

バックアップは30日で設定してみます。
まずは「オブジェクトを削除する」を選びます。

画像20

ここが年齢を30日に設定して作成します。
日本語として判りにくいですが、年齢30日で30日経ったという事です。

画像21

これで毎日のバックアップが行われるようになります。

この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
ありがとうございます。
ゲーム制作チーム。主にUnityでスマフォゲームを作っています。 コンシューマゲームを手伝う事もあります。FireBaseなども使い新しい仕組みを模索してます。