Cloud Functions for FirebaseをPythonで使ってみた

2024.05.13

こんにちは、ゲームソリューション部のsoraです。
今回は、Cloud Functions for FirebaseをPythonで使ってみたことについて書いていきます。

前提条件

・npmがインストール済みであること
・python3.12がインストール済みであること(バージョンについては、つまづいた部分があるため後に記載します)
・Firebaseのプロジェクトが作成済みであること
・FirebaseのプランがBlazeプランであること

Cloud Functions for Firebaseとは

Cloud Functions for Firebaseは、Google Cloudのサーバレスの関数実行環境であるCloud FunctionsをFirebase用にラップしたものです。
Cloud FunctionsはAWSでいうとLambdaのようなものだと思います。

Cloud Functions for Firebaseのトリガーとして、リクエストへの応答だけでなく、スケジュールやFirestore(ドキュメントDB)の変更をトリガーにすることも可能です。

Firebaseのアカウントを作成した初期の無料プラン(Sparkプラン)では利用できないため、利用するためには従量課金プラン(Blazeプラン)にする必要があります。
無料枠もあるため、テスト用に少し触る程度では料金が発生するところまではいかないと思います。
Firebase Pricing

Cloud Functions for Firebaseで使用できる言語について、JavaScriptとTypeScriptのみでしたが、プレビュー版としてPythonも使用することができます。

Cloud Functions for Firebase用のフォルダ作成

Cloud Functions for Firebaseの関数作成やデプロイはFirebaseのGUI上ではできないため、Firebase CLIをインストールして行います。
以下にデプロイまでのコマンドを記載します。

# Firebase CLIのインストール
$ npm install -g firebase-tools

# パスを通す
$ echo 'export PATH="`npm config get prefix`/bin:$PATH"' >> ~/.profile
$ source ~/.profile

# Firebase CLIのバージョン確認
$ firebase -V
13.8.3

# Firebaseへのログイン
# 表示されるURLにアクセスして認証する
$ firebase login
# ローカル接続周りでエラーが出る場合は以下コマンド
$ firebase login --no-localhost

# Firebaseプロダクトの選択、Cloud Functions用のフォルダの作成
$ firebase init
######## #### ########  ######## ########     ###     ######  ########
##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
######    ##  ########  ######   ########  #########  ######  ######
##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
##       #### ##     ## ######## ########  ##     ##  ######  ########

# 使用するFirebaseのプロダクトを選択
# 矢印キーでFunctionsに合わせてSpaceで選択してEnterで決定
? Which Firebase features do you want to set up for this directory? Press Space to
select features, then Enter to confirm your choices. Functions: Configure a Cloud
Functions directory and its files

# 使用するプロジェクトの選択(今回は既存のものを選択)
=== 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.
? Please select an option: Use an existing project

# 使用する言語の選択(今回はPythonを選択)
=== Functions Setup
Let's create a new codebase for your functions.
A directory corresponding to the codebase will be created in your project
with sample code pre-configured.
See https://firebase.google.com/docs/functions/organize-functions for
more information on organizing your functions using codebases.
Functions can be deployed with firebase deploy.
? What language would you like to use to write Cloud Functions? Python
✔  Wrote functions/requirements.txt
✔  Wrote functions/.gitignore
✔  Wrote functions/main.py

# 依存関係のインストール
? Do you want to install dependencies now? Yes
i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...
✔  Firebase initialization complete!

Cloud Functions for Firebaseのデプロイ

コード内のコメントアウトを外す

初期コードのままデプロイすると、エラーにはならないもののデプロイもされないため、コメントアウト部分を外します。
以下コード内に記載のコメントは、説明用に付け足したものなので記載しなくても問題ないです。

main.py

from firebase_functions import https_fn
from firebase_admin import initialize_app

# 新しいAppインスタンスの初期化
initialize_app()

# https_fn.on_requestは、エンドポイントから関数を呼び出す
# https_fn.on_callにすると、関数をFirebase SDKを使って呼び出す
@https_fn.on_request()
# def xxの部分がリクエスト時のパスになる
def on_request_example(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

デプロイ

作成した関数をデプロイします。
ローカルでのテストも可能です。

# (テスト用)Cloud Functionsのローカルでの実行
$ firebase serve --only functions

# デプロイ
$ firebase deploy
# Cloud Functionsの特定の関数のみデプロイは以下
$ firebase deploy --only functions:function_name

# Cloud Functionsの削除(FirebaseのGUI上でも削除可能)
firebase functions:delete function_name

ブラウザで{トリガーのリクエスト下に記載のURL}/on_request_exampleにアクセスしてみると、Hello world!が表示されます。

つまづいたポイント

デプロイまでの間で、私がつまづいたポイントを記載します。

Pythonのバージョン問題

2024年5月13日現在で公式ページにPythonの対応しているバージョンが3.10と3.11という記載があったため、3.11にしてfirebase initを実行すると、venvが作成できませんでした。(翻訳されていないだけかと思い、英語でも確認しましたが同様の記載でした)
はじめに: 最初の関数の記述、テスト、デプロイ  |  Cloud Functions for Firebase

# 依存関係のインストール
? Do you want to install dependencies now? Yes
/bin/sh: 1: .: cannot open /home/{user}/test/functions/venv/bin/activate: No such file
/bin/sh: 1: .: cannot open /home/{user}/test/functions/venv/bin/activate: No such file
i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...
✔  Firebase initialization complete!

# 作成されたファイルの確認(venvが作成されていない)
$ ls
main.py  requirements.txt

一旦デプロイしてみようとすると、Python3.12が求められているっぽいエラーが出ました。

$ firebase deploy
Error: Failed to find location of Firebase Functions SDK: Missing virtual environment at venv directory. Did you forget to run 'python3.12 -m venv venv'?

その後は、Python3.12にしてfirebase initを実行してみると、自動でvenvも作成されてうまくいきました。
デプロイ後のFunctionsの言語を確認してみると、言語:python312になっていたため、Python3.12で動いてそうでした。

最後に

今回は、Cloud Functions for FirebaseをPythonで使ってみたことを記事にしました。
どなたかの参考になると幸いです。