Next.js × Firebase Auth で複数プロバイダを紐付ける

Firebase

Next.js

TypeScript

はじめに

今回、GitHubログインを行った後にそのアカウントをTwitterのアカウントと紐付けるということを行ったので、その時のメモとしてこれを残しておこうと思います。

Firebase Authenticationの設定

Firebaseコンソールからプロジェクトを作成後、「構築」からAuthenticationを選択。

次にログイン方法を選択する。ログインプロバイダから新しいプロバイダを追加を選択し、自身のログインしたいものを選ぶ。

今回私はGitHubとTwitterを選択しました。

次に、プロジェクトの設定からマイアプリを追加。今回はウェブアプリを選択しました。

アプリ作成後に生成される firebaseConfig を保持しておきます。

const firebaseConfig = { apiKey: "**********************************", authDomain: "***************************", projectId: "*******************************", storageBucket: "***********************", messagingSenderId: "*****************", appId: "**********************************", measurementId: "***********************" };

こんな感じのやつ

コードを書いていく

まずは firebse プラグインをインストール

$ yarn add firebase

次に設定ファイルの追加

~/constant/index.ts
import { FirebaseOptions } from "firebase/app"; export const firebaseConfig: FirebaseOptions = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID };

(さっきのfirebaseConfigの値はenvにおいておく)

~/infra/firebase.ts
import { FirebaseApp, initializeApp } from "firebase/app"; import { Auth, getAuth } from "firebase/auth"; import { Firestore, getFirestore } from "firebase/firestore"; import { firebaseConfig } from "~/constant"; export const firebase: FirebaseApp = initializeApp(firebaseConfig); export const firebaseAuth: Auth = getAuth(firebase); export const firestore: Firestore = getFirestore(firebase);

ログイン、連携の処理
Githubログイン → Twitter連携の想定

~/hook/auth.ts
import { GithubAuthProvider, TwitterAuthProvider, signInWithPopup, linkWithPopup, signOut, } from "firebase/auth"; import { firebaseAuth } from "~/infra/firebase"; export const useAuth = () => { // GitHubでログイン const githubLogin = async () => { const provider = new GithubAuthProvider(); return await signInWithPopup(firebaseAuth, provider); }; // ツイッター連携 const twitterLink = async () => { const provider = new TwitterAuthProvider(); if (firebaseAuth.currentUser) { return await linkWithPopup(firebaseAuth.currentUser, provider); } }; // ログアウト const logout = () => { return signOut(firebaseAuth); }; return { githubLogin, twitterLink, logout }; };

あとはこれらをpage内で呼び出すだけ

const { googleLogin } = useAuth();

こんな感じで持ってこれる。

ちなみに、signInWithPopup() では onAuthStateChanged() が実行されるが、 linkWithPopup() では実行されないので注意。

このせいでDBからデータを取ってくるタイミングなどで手間取りました...

みきどーざん

@take_cantik

目次