Firebase JavaScript SDK が、v9で大きく変わりました。 バージョンアップに伴い、Authenticationの実装の仕方もかなり変わったため、メモを残しておきます。
Firebase JavaScript SDK v9 の仕様
v9では、SDKの中から必要なモジュールだけを読み込んで利用する「Tree Shaking」という手法を採用しています。webpackなどで採用されている手法です。
JavaScript SDK v9 を利用した認証の実装
今回の変更を踏まえて、Firebase Authenticationの認証を実装してみました。
ディレクトリ構成
今回のサンプルはこんな構成で作成しました。
├── dist
│ ├── bundle.js
│ └── index.html
├── firebase.json
├── node_modules
├── package-lock.json
├── package.json
├── src
│ └── index.js
└── webpack.config.js
srcディレクトリ配下のindex.js がエントリーポイント。
dist/bundle.js が、SDKのモジュールをロード後、出力したJSファイルとなります。
以下、各種ファイルの記述
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devtool: 'eval-source-map',
};
package.json
{
"name": "auth-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode=development"
},
"author": "",
"license": "ISC",
"dependencies": {
"firebase": "^9.6.6"
},
"devDependencies": {
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2"
}
}
firebase.json
今回は「dist」が公開ディレクトリになるよう設定しました。
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
index.jsはこんな感じに書いてみました。
今回は、Googleアカウントを利用した認証のみ許可しています。
import { initializeApp } from "firebase/app";
const firebaseConfig = {
/*
Firebaseから Config を取得して書き込みます
*/
};
const app = initializeApp(firebaseConfig);
import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
const auth = getAuth();
const provider = new GoogleAuthProvider();
window.signIn = function() {
signInWithPopup(auth, provider)
.then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
// ...
}).catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
const email = error.email;
const credential = GoogleAuthProvider.credentialFromError(error);
// ...
});
}
window.signOut = function() {
auth.onAuthStateChanged(user => {
auth.signOut()
.then(() => {
console.log('ログアウトしました');
location.reload();
})
.catch((error) => {
console.log(`ログアウト時にエラーが発生しました (${error})`);
});
});
}
auth.onAuthStateChanged(user => {
if (user) {
const signOutMessage = `
<p>Hello, ${user.displayName}!<\/p>
<button class="btn btn-primary" type="submit" onClick="signOut()">サインアウト<\/button>
`;
document.getElementById('auth').innerHTML = signOutMessage;
console.log('ログインしています');
} else {
const signInMessage = `
<button class="btn btn-primary" type="submit" onClick="signIn()">サインイン<\/button>
`;
document.getElementById('auth').innerHTML = signInMessage;
}
});
index.html
webpackで出力した「bundle.js」をロードしています。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Firebase Authentication WebPack</title>
<script src="bundle.js"></script>
</head>
<body>
<h1>Firebase Authentication WebPack</h1>
<div id="auth"></div>
</body>
</html>
設定が終わったら、webpackでJSファイルを出力します。
npm run build
出力後、動作確認。意図通り動作しました。
参考ドキュメント
Firebase JavaScript SDK v9 と webpack の組み合わせについては、下記のドキュメントが詳しかったです。これを読めば大体理解できると思います。