背景
React×Firebaseで非ログイン時にアクセス制限を実装しようとしたところ、
意外と記事が少ないのと、Firebaseの仕様理解が甘く詰まってしまったので記事にまとめようと思います。
実装
import React, { useState, useEffect } from "react";
import { onAuthStateChanged } from "firebase/auth";
import { useNavigate } from "react-router-dom";
const Home = () => {
const [userAuth, setUserAuth] = useState();
const navigate = useNavigate();
useEffect(() => {
// ログイン認証
onAuthStateChanged(auth, (user) => {
if (!user) {
navigate("/signin");
} else {
setUserAuth(user);
}
}, []);
});
if (userAuth !== null) {
return (
<>
<h1>Home</h1>
</>
)
}
}
onAuthStateChanged
を実行することでauth
が保持している値 (ユーザー情報)がuser
に入り、
引数となるuser
が空の時にはsignin
へ戻るようになり、そうではない時にはsetUserAuth
を実行する
なぜifを使う必要があるのか
onAuthStateChangedは非同期処理であるため、authオブジェクトの状態を待って認証情報を取得する必要があるため上記のようにifを使って条件分けを行う必要がある。
上記に合わせてreturn時にもif (userAuth !== null)
を使い、ログイン時にはsetUserAuth
を実行し、userAuth
にauth
の値が格納されるのでuserAuth
がnull
ではなくなり、レンダリングされるようになっている
まとめ
- アクセス制限をかけるためには
onAuthStateChanged
の非同期である特性を意識する必要がある - ifを使って渡せる値があるかどうかで判定
- 非同期難しい