FirebaseのCloud Functionsを利用すると巷で話題のサーバレスなシステムを構築することができます。外部にURLを公開してRESTful APIなども作成できますし、Firebase内のイベントに合わせて特定の処理を実行することが可能です。もちろんFirestoreやRealtimeDatabaseなどと連携することもできます。
functionsはNode.js上で動作するプログラムを記述することになりますので、すでにJavaScriptやTypeScriptの経験がある方なら特別な言語仕様を覚える必要が無いのも魅力でしょう。
CloudFunctionsでHelloWorld
準備
Firebaseのコンソールからプロジェクトを作成します。すでに利用しているプロジェクトがある場合はそちらを使用しても大丈夫です。 blog.katsubemakito.net
その後CLIツールのインストールを行います。詳しくは以下のページの「1 環境の準備」の項、Googleアカウントでログインするまでの部分を参照ください。 blog.katsubemakito.net
ディレクトリの初期化
すでにFirebaseで利用しているディレクトリがあればそちらに、無ければ新規にディレクトリを作成しカレントディレクトリを移ります。今回はすでに使ってるプロジェクトがあったのでそちらに移動しました。
$ cd miku3net
ではおもむろに初期化コマンドを叩きます。
$ firebase init functions
ウェルカムメッセージが表示された後にいくつか質問を求められます。 最初に利用するプロジェクトを選択します。既存のディレクトリを利用した場合はスキップされます。
=== Project Setup First, let's associate this project directory with a Firebase project. You can create multiple project aliases by running firebase use --add, but for now we'll just set up a default project.
次にCloudFunctionsで利用する言語をJavaScript
とTypeScript
のいずれかから選択します。ここではJavaScriptを選びました。ESLint
を利用するか聞かれるので任意でYes/Noを選択。ここではNoを選びました。最後に必要なモジュールをインストールするか聞かれますのでYesを選択。ネットワーク経由でモジュールをガンガン取ってきてくれます。
=== Functions Setup A functions directory will be created in your project with a Node.js package pre-configured. Functions can be deployed with firebase deploy. ? What language would you like to use to write Cloud Functions? JavaScript ? Do you want to use ESLint to catch probable bugs and enforce style? No ✔ Wrote functions/package.json ✔ Wrote functions/index.js ✔ Wrote functions/.gitignore ? Do you want to install dependencies with npm now? Yes
最終的に以下のようなメッセージが表示されれば成功です。
✔ Firebase initialization complete!
functions
という名前のフォルダが作成され、中に以下のようなファイルが生成されています。
スクリプトの準備
functions/index.js
を開き以下のようなコードを準備します。実際にはコメントアウトするだけですね。
const functions = require('firebase-functions'); // // Create and Deploy Your First Cloud Functions // // https://firebase.google.com/docs/functions/write-firebase-functions exports.helloWorld = functions.https.onRequest((request, response) => { response.send("Hello from Firebase!"); });
functionsはNode.js上で動作するコードを書くことになりますので、ブラウザに依存した過去のコードなどを意識する必要はなくES2015相当の仕様で記述することができます。 ※Node v6 または Node v8
デプロイ
先ほど準備したファイルを本番サーバへ反映します。こちらもコマンド一発です。この処理はちょっと時間がかかりますので最初は不安になりますが大丈夫です、じっと待機します。
$ firebase deploy --only functions
最終的にDeploy complete!
と表示が出ればデプロイに成功しています。早速Function URL (helloWorld)
と表示されている箇所のURLへアクセスしてみましょう。
=== Deploying to 'test-f76bc'... i deploying functions i functions: ensuring necessary APIs are enabled... ✔ functions: all necessary APIs are enabled i functions: preparing functions directory for uploading... i functions: packaged functions (29.37 KB) for uploading ✔ functions: functions folder uploaded successfully i functions: creating Node.js 6 function helloWorld(us-central1)... ✔ functions[helloWorld(us-central1)]: Successful create operation. Function URL (helloWorld): https://us-central1-test-f76bc.cloudfunctions.net/helloWorld ✔ Deploy complete!
またFirebaseのコンソールからも作成されたことが確認できます。
その他
東京リージョンを利用する
デフォルトだとus-central1
に固定で作成されてしまうため、このリージョンを変更したくなりますよね。最初はpackage.json
で指定したり、コマンドのオプションにあるのかと思ったのですが、どうもソースコード上で直接指定するようです。
const functions = require('firebase-functions'); exports.helloWorld = functions.region('asia-northeast1').https.onRequest((request, response) => { response.send("Hello from Firebase!"); });
Nodeのバージョンを指定する
デフォルトだとNode v6で動作するのですが、さすがにちょっと古いのでv8で動かす設定を行います。
functions/package.json
を開き、以下を追加します。
"engines": {"node": "8"}
全体としては以下のようなイメージ(コメント行は記入しないでください)
{ "name": "functions", "description": "Cloud Functions for Firebase", "scripts": { "serve": "firebase serve --only functions", "shell": "firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log" }, "dependencies": { "firebase-admin": "~7.0.0", "firebase-functions": "^2.2.0" }, "private": true, // ↓こいつを追加 "engines": {"node": "8"} }
作成済みのFunctionを削除する
CLIからだと以下の通り。
$ firebase functions:delete helloWorld