【Next.js × Firebase】Authenticationで爆速Googleログイン実装
はじめに
前回はfirebaseのサービスfirestoreを使ってDB構築を行いました。今回は同じくfirebaseのサービスのAuthenticationを使ってGoogleログインを導入します。
Firebaseセットアップ
前回の記事で紹介したので省略します。
Authenticationセットアップ
Authenticationを選択>始める
プロバイダーを選択(今回はGoogleを選択)
有効にする>メールアドレス入力>保存
以上で完了です。簡単...
Firebase+Authentication初期化処理
Next.jsの記述に移ります。
config情報はプロジェクトの設定に記載されているものを環境変数で管理しています。
import { initializeApp } from "firebase/app";
import { GoogleAuthProvider, getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: process.env.FIREBASE_APIKEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STRAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MASSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Cloud Firestore and get a reference to the service
export const db = getFirestore(app);
export const auth = getAuth(app);
export const provider = new GoogleAuthProvider();
SignInコンポーネント作成
SignInコンポーネントはログイン状態を見てサインインボタンかログアウトボタンを出し分ける役割をしています。
コンポーネントに切り出した理由としては後ほど紹介するGoogleサインインの関数(signInWithPopup
)はクライアントコンポーネントでしか使用できず"use client"の記述をしているためです。(ちなみにNext.js v14 app Routerを使用しています。)
このコンポーネントを親のサーバーコンポーネントでimportして使います。
"use client";
import { auth, provider } from "@/lib/firebase/firebase";
import { signInWithPopup } from "firebase/auth";
import { useRouter } from "next/navigation";
import React from "react";
import { useAuthState } from "react-firebase-hooks/auth";
export const SighIn = () => {
const [user] = useAuthState(auth);
const router = useRouter();
const signInWithGoogle = () => {
signInWithPopup(auth, provider).then((result) => {
console.log(result);
router.push("/tasks");
});
};
const signOutWithGoogle = () => {
auth.signOut();
};
return (
<>
{user ? (
<button
onClick={signOutWithGoogle}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded shadow"
>
ログアウト
</button>
) : (
<button
onClick={signInWithGoogle}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded shadow"
>
Googleログインして開始する
</button>
)}
</>
);
};
まずサインインボタンとログアウトボタンを作成します。
サインイン処理
signInWithPopup
を使用し、引数には先ほどexportしたauth
とprovider
を渡します。成功したら"/tasks"へ遷移させています。
ログアウト処理
auth
の中にsignOut
メソッドが提供されているためそちらを使用します。
ログイン状態を確認
ログイン状態を提供してくれる便利なフックがあるためインストールします。
npm i react-firebase-hooks
useAuthState
をインポートします。
useAuthState
の引数にauth
を渡しユーザー情報を受け取ります。未ログインの場合はnull
になります。
ユーザー情報が存在したらログアウトボタンに、null
の場合はサインインボタンを表示するようにしています。
ログインしてみる
サインインボタンを押下します。
Googleログインのポップアップが出ました。
ログイン成功!
おまけ
APIKEYが無効エラーがでたが?【解決】
FirebaseError: Firebase: Error (auth/invalid-api-key).
APIKEYを環境変数においたら無効とか言われました!
envを確認しても値は合ってる。。。
これですがおそらく原因は「exportしたauthの機能をクライアント側で使っているため」です!
process.env.FIREBASE_APIKEY
この書き方はサーバー側でしか参照されないんですね〜
クライアント側で使いたかったらNEXT_PUBLIC_
をつけるか、Next.jsのenv機能を使用してクライアント側に値を流してあげる必要があります!
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
FIREBASE_APIKEY: process.env.FIREBASE_APIKEY,
},
};
export default nextConfig;
これでエラーが発生しなくなりました!
まとめ
ログイン機能は外部に任せるのが安心安全なので個人開発ではfirebaseのAuthenticationを利用しようと思います!
Discussion