概要
Cloud Functions for Firebaseを使用して、任意時間ごとに実行される関数を作成します。
目的としては、Next.jsで作成したサイトが、SSG時にAPI経由でデータを取得しているため、VercelのDeploy Hooksを使って定期的な更新をかけたいと思いました。サイトを更新(リビルド)することで再びSSGされるので、最新のAPIデータがサイトに反映される設計です。
Next.jsのサイト設計に興味のある方は、以下の記事を参考にしてみてください。
スケジューラ関数について、私の環境ではfirebase-toolsを使用したdeployがうまくいかず、少し強引な解決方法を取りました。
この記事では、その解決方法をメインにまとめいています。
ただし、明確な解決方法はわかっていません。こうすれば、一応動くものはできましたという感じです。
もし、こんな面倒な方法を取らなくてもこうすれば解決できるよ!と、解決方法をご存知の方は、是非教えてください。
バージョン
- Node.js - v14.17.1
- npm - 7.6.3
- firebase-tools(firebase) - 9.16.6
関数の作成
Firebase 初期設定
まず、以下のことを済ませておきます。
1. Firebaseプロジェクトの作成
Cloud Functions for Firebaseを利用するためには、有料プランに切り替える必要があります。
2. firebase-toolsのインストール
npm i -g firebase-tools
3. ローカルプロジェクトの作成・初期化
firebase init
Functions(Cloud Functions for Firebase)
、既存のプロジェクト → 1で作成したプロジェクト
、TypeScript
を選択します。
4. パッケージ インストール
作成されたfunctionsフォルダ以下で、パッケージをインストールします。
C:\Users\Projects\deploy-hooks\functions> npm i axios dotenv
コーディング
ドキュメントを参考にコーディングします。
import axios from 'axios';
import * as dotenv from 'dotenv';
import * as functions from 'firebase-functions';
dotenv.config()
const DEPLOY_HOOKS_URL = process.env.PORTFOLIO_DEPLOY_HOOKS!
export const VercelDeployHooks = functions
.region('asia-northeast1')
.pubsub.schedule('every 24 hours')
.timeZone('Asia/Tokyo')
.onRun(async context => {
functions.logger.info('VercelDeployHooks:onRun!')
await axios.get(DEPLOY_HOOKS_URL)
return null
})
Deploy & Error...
これで、あとはFirebaseにデプロイすれば終わり!
npm i deploy
のはずでした....
以下のようなエラーが出力され、正常にデプロイできません...
+ functions: Finished running predeploy script.
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
+ functions: required API cloudbuild.googleapis.com is enabled
+ functions: required API cloudfunctions.googleapis.com is enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (49.44 KB) for uploading
i pubsub: ensuring required API pubsub.googleapis.com is enabled...
i scheduler: ensuring required API cloudscheduler.googleapis.com is enabled...
+ scheduler: required API cloudscheduler.googleapis.com is enabled
+ pubsub: required API pubsub.googleapis.com is enabled
+ functions: functions folder uploaded successfully
i functions: creating Node.js 14 function VercelDeployHooks(asia-northeast1)...
+ functions[VercelDeployHooks(asia-northeast1)]: Successful create operation.
i functions: cleaning up build files...
Functions deploy had errors with the following functions:
VercelDeployHooks(asia-northeast1)
To try redeploying those functions, run:
firebase deploy --only "functions:VercelDeployHooks"
To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.
npm ERR! code 1
npm ERR! path C:\Users\Projects\deploy-hooks\functions
npm ERR! command failed
npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c firebase deploy --only functions
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\AppData\Local\npm-cache\_logs\2021-08-29T05_31_18_042Z-debug.log
例えば、以下の記事のようなAPI関数の場合、これまでの手順で正常にデプロイできました。でもなぜか、スケジューラ関数ではエラーになります。
エラーの解決方法
原因の推測
API関数との差異は、スケジューラ関数ではバックグラウンドでPub/Sub API、Cloud Scheduler APIを使用していることです。
Google Cloud PlatformのAPIとサービスを確認すると、このAPIにうまくアクセスできずにエラーになっているようです。
このあたりの推測で、調べてみると同じようなエラーに直面している方がいました。
解決方法として、
Cloud Scheduler にアクセスして手動でPubSubジョブを作ると直る、以降のデプロイも落ちなくなる
とあるので、試してみます。
Firebase の状況
Firebaseコンソールを確認すると、firebase-toolsを使用したデプロイは失敗しましたが、関数自体のアップロードはできています。ただし、設定した時間になっても動きません。
Cloud Scheduler の設定
Google Cloud PlatformのCloud Schedulerで、ジョブを作成します。
名前や説明、メッセージは任意みたいですが、index.tsで記述したものと合わせておきます。
頻度とタイムゾーンは、index.tsで記述した内容を無視してこちらの設定が優先されます。
ターゲットタイプをPub/Subにして、トピックでデプロイしたスケジューラ関数を選択します。
頻度について、cron形式で設定します。以下を参照してください。
Cloud Scheduler の動作確認
作成すると、ダッシュボードに登録されます。作成したスケジューラ関数は1日に1回
実行されるように設定したので、**[今すぐ実行]**を押してテストしてみます。
FirebaseコンソールのFunctionsのログをみると、VercelDeployHooks:onRun!
と表示されています。
functions.logger.info('VercelDeployHooks:onRun!')
そして、Vercelのダッシュボードでは、ビルドされているのがわかります。
おまけ:有料プランについて
ドキュメントにもある通り、Cloud Functions for Firebaseは有料プランで使用することができます。また、スケジューラ関数は、アカウントごとに3つまで無料です。
Firebase プロジェクトでこのソリューションを使用するには、プロジェクトで Blaze 料金プランを利用している必要があります。Blaze プランをまだ利用していない場合は、料金プランをアップグレードしてください。
課金は必須ですが、Cloud Scheduler の各ジョブのコストは月額 $0.10(USD)であり、Google アカウントごとに 3 つのジョブを無料で使用できるため、全体的なコストは管理可能であることが期待できます。Blaze の料金計算ツールを使用すると、予想使用量に基づく料金見積もりを作成できます。