Cloud Functions for FirebaseでPythonを使うことはできません。Cloud Functions for Firebaseのドキュメントを見れば分かるようにNode.jsにしか対応していないからです。でも、ちょっとした裏技を使うとPythonなど他の言語を使うことができます。
Cloud Functions for Firebase とCloud Functionsの関係
簡単に言うと、Cloud Functions for Firebase は、 Cloud Functionsのラッパーみたいなものです。裏側ではCloud Functionsが動いており、それを使うためのデプロイツールとAPIがFirebase側でも提供されているだけなのです。つまり、Cloud Functionsを直接使えばFirebaseとFunctionsを組み合わせることができます。
コマンドで言うと以下の通りで、これで検索すればそれぞれのドキュメントを見ることができるでしょう。
# Cloud Functions for Firebaseの場合
firebase deploy --only functions
# Cloud Functions の場合
gcloud functions deploy
ここで疑問に思うのは、Cloud Functions for Firebase がラッパーとして何をしているか、それをラッパーなしで実現できるかということです。Cloud Functions for Firebase は2つのことをしています。
-
firebase deployでは、プログラム内でメソッドの名称とトリガーを指定できる。gcloud functions deploy では、トリガーの種類、イベント名と実行するメソッドをコマンドラインの引数で指定する。Firebase独自のトリガーもすべてgcloud functions deployで利用可能なので、機能的な差異はない。(イベントリストはgcloud functions event-types listを参照)。以下はPythonの場合のサンプル。
gcloud functions deploy hello_world --region=asia-northeast1 --runtime=python310 --source=./src --entry-point=hello_world --trigger-http
-
Cloud Functions for Firebase ではonCallというトリガーがあり、これを使うとFirebaseからの呼び出し時の認証を自動で行ってくれる。これは、Python, Java, C#, GOで提供されているfirebase_adminツールを使えば対応可能。Ruby, PHPの場合、firebase admin apiは提供されていないが、JWTのパーサーを使えば対応可能と思われる。以下はPythonの場合のサンプル。
from typing import Union
from flask import jsonify, Request, Response
from flask_cors import cross_origin
from firebase_admin import auth, initialize_app
firebase_app = initialize_app()
def getToken(request: Request) -> Union[dict, None]:
authorizationHeader = request.headers.get("Authorization", None)
encodedToken = authorizationHeader.removeprefix("Bearer ") if authorizationHeader else None
token = auth.verify_id_token(encodedToken) if encodedToken else None
return token
@cross_origin()
def hello_world(request: Request) -> Response:
body = request.get_json()
token = getToken(request)
isMember = bool(token.get("role")) if token and type(token) == dict else False
return jsonify({
"data": {
"token": token,
"isMember": isMember,
"body": body,
"token": token
}
})
まとめ
こう見ると、Cloud Functions for Firebaseがかなり薄いラッパーであり、Node.js以外の言語でFunctionsを書くのも、そんなに難しくないことが分かります。自分はバックエンドをNode.jsで書くことが多いのですが、データ分析や機械学習の用途でPythonを使う場合、わざわざLambdaを使ったりコンテナを立てるより、Cloud Functionsを直接使う方法を知っておいた方が便利ではないかと思います。