Firebaseでは、ログイン機能は、Authenticationプロジェクトがあるため、簡単に作成することができます。
しかし、こんな場合にはどうでしょう。
“OAuth”と、”メール/パスワード”2種類のログインプロバイダを使用する。
こんなときにFunctionsが活躍します。
Functionsとは
それでは、Functionsとは何かから見てみましょう。
公式ドキュメントには、以下のように記載されています。
Firebaseの機能とHTTPSリクエストによってトリガーされたイベントに応じてバックエンドコードを自動的に実行できるサーバーレスフレームワーク
https://firebase.google.com/docs/functions?hl=ja
要点は以下になります。
- Googleのサーバーで関数の管理をしてくれる
- HTTPリクエストを使用して関数を直接起動できる
Functionsの始め方
それではFunctionsを使っていきましょう!
前提として、FirebaseのプロジェクトとFirestoreは既に作成済みのものとします。
FunctionsをFirebaseコンソールの構築から、Firestoreと同じように追加します。
ちなみにFunctionsを使用するには、有料プランのBlazeにアップグレードする必要があります。
Functionsの登録を行うと、親切に手順を教えてくれます。
firebase-toolsをインストールしましょう!
$ npm install -g firebase-tools
$ firebase init
$ firebase deploy
これによりFunctionsのdeployができますが、今は実行する必要はありません。
コンソールでのFunctionsの作成ができました。
プロジェクトの初期化
CLIでfunctionsの初期化を行っていきます。
$ firebase init functions
上記コマンドが正常に完了すると、以下のディレクトリ構成のファイルが生成されます。
myproject
+- .firebaserc # Hidden file that helps you quickly switch between
| # projects with `firebase use`
|
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
|
+- .eslintrc.json # Optional file containing rules for JavaScript linting.
|
+- package.json # npm package file describing your Cloud Functions code
|
+- index.js # main source file for your Cloud Functions code
|
+- node_modules/ # directory where your dependencies (declared in
# package.json) are installed
生成されたファイルに手を加えていきましょう。
ファイル編集
対象ファイル
Functionsを使うために編集が必要となる対象のファイルは、以下の5つです。
- functions/index.js
- src/UserCreateForm.tsx
- src/Login.tsx
- src/firebase.ts
- src/auth.ts
ディレクトリ構成は、本来はcompontsや、libなど使用しますが、ここでは分かりやすいようfunctionsとsrcディレクトリのみとしています。
見える部分から順番に見ていきましょう!
以下の流れの機能を作成します。
- src/UserCreateForm.tsx でユーザーを作成し、emailとpasswordを設定する
- 1で作られたデータを使ってsrc/Login.tsx でログインする
src/firebase.ts
Functionsを使えるようにするために、まずfunctiosの定義をします。
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";
import { getFunctions } from "firebase/functions";
const firebaseConfig = {
apiKey: import.meta.env.VITE_API_KEY,
authDomain: import.meta.env.VITE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_PROJECT_ID,
storageBucket: import.meta.env.VITE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_APP_ID,
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const auth = getAuth(app);
export const functions = getFunctions(app, 'asia-northeast1');
src/UserCreateForm.tsx
ユーザー登録のsubmit関数内を以下に記します。
import { httpsCallable } from "firebase/functions";
const submit = async (data: User) => {
try {
const createUser = httpsCallable(functions, "create_user");
const res = await createUser({
email: data.email,
password: data.password,
});
} catch (error) {
console.log(error);
}
};
httpsCallableを使ってcreate_user関数を呼び出します。
以下公式ドキュメントです。
呼び出し元のcreate_user関数を作っているところを見てみましょう。
functions/index.js
Cloud Functions と Admin SDK モジュールをインポートします。
// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
先程呼び出しをしたcreate_user関数の中身を記述します。
exports.create_user = functions
.region("asia-northeast1")
.https.onCall((data, context) => {
const { email, password } = data;
return new Promise((resolve, reject) => {
app
.auth()
.createUser({
email,
password,
})
.then((user) => {
resolve({ user });
})
.catch((error) => {
console.log("Error creating new user:", error);
reject(error);
});
});
});
regionを指定して、onCallというものを使用します。
functions.https.onCall
を使用して、dataとcontextの2つのパラメータを取得して、HTTPS 呼び出し可能関数を作成します。
そして、createUserでユーザーを作成します。
全体としては以下のようになります。
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const app = admin.initializeApp();
exports.create_user = functions
.region("asia-northeast1")
.https.onCall((data, context) => {
const { email, password } = data;
return new Promise((resolve, reject) => {
app
.auth()
.createUser({
email,
password,
})
.then((user) => {
resolve({ user });
})
.catch((error) => {
console.log("Error creating new user:", error);
reject(error);
});
});
});
これで、authにuserの登録ができたので、ログイン画面を作っていきましょう!
src/Login.tsx
ログインのボタン押下時のsubmit関数のみを以下に記します。
import { login_email } from "../../auth";
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
login_email(email, password);
};
submit時に、login_emailという関数に、ログインフォームに入力したemailとpasswordを渡しています。
このlogin_email関数は、auth.tsで作成しているので最後にそこを見て終わりにしましょう!
src/auth.ts
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../firebase";
export const login_email = (email: string, password: string) => {
signInWithEmailAndPassword(auth, email, password)
.then((result) => {
console.log("USER", result.user);
})
.catch((error) => {
const errorMessage = error.message;
alert(errorMessage);
});
};
signInWithEmailAndPasswordを使用してauthにユーザー情報を登録します。
以上で、Functionsを使ったログイン機能を作成することができました。
お読みいただきありがとうございました!
コメント