๊ทธ๋์ ๋ ๋ก๊ทธ์ธ๋ ํ๋๋ฐ ์์ง ์ด๋ฉ/๋น๋ฒ ์ ๋ ฅ์ฐฝ์ด ๋ณด์ด๋ ๊ฒ์ด ๊ฑฐ์ฌ๋ฆฐ๋ค.
ํ์ฌ currentUser ์์ฑ์ ์ฌ์ฉํ์ฌ ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ค๊ณ ์๋ค.
์ด๋ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์ํ๊ฐ ์๋๋ผ๋ฉด currentUser ๊ฐ์ null๋ก ํ์๋๋ค.
๊ทธ๋ฐ๋ฐ ํ์ฌ App์ด ๋ก๋๋ ๋, ๋๋ฌด ๋นจ๋ฆฌ ๋ก๊ทธ๋๊ธฐ ๋๋ฌธ์ firebase๋ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ํ๋์ง ์ํ๋์ง ํ์ธํ ์๊ฐ์ด ์๋ค. ๋ฐ๋ผ์ App์ด ์์ํ๋ฉด ํญ์ ๋ก๊ทธ์์ ์ํ๊ฐ ๋๊ณ , authService.currentUser๋ ํญ์ null, ์ฆ ๋ก๊ทธ์ธํ ์ ์ ๊ฐ ์๋ ์ํ๊ฐ ๋๋ค.
์ฆ, Auth ๊ฐ์ฒด์ ์ด๊ธฐํ๊ฐ ์๋ฃ๋์ง ์์ currentUser๊ฐ null์ธ ๊ฒ์ด๋ค.
๐ ๊ด์ฐฐ์๋ฅผ ์ฌ์ฉํด ์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ํ๋ฅผ ์ถ์ ํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋๋ฐ, ์ผ๋จ ์๋ ์ฒ๋ผ ์์ฑํ๋ฉฐ ํ์ฌ ์ํ๋ฅผ ์ ๊ฒํด ๋ณด์.
์ค๊ฐ์ setInterval()์ ์ฌ์ฉํ์ฌ ์๊ฐ ๊ฐ๊ฒฉ์ ์ฃผ๊ณ ์ฝ์์ currentUser๋ฅผ ์ฐ์ด๋ณด์.
//์ ๋ ๊ฒฝ๋ก(absolute import)
import AppRouter from "components/Router";
import { useState } from "react";
//์ ๋ ๊ฒฝ๋ก(absolute import)
//fbase์์ authService ๊ฐ์ ธ์ค๊ธฐ(export๋ก ๋ด๋ณด๋๊ธฐ ๋๋ฌธ์ {} ์ค๊ดํธ ์ณ์ ๊ฐ์ ธ์์ผ ํจ)
import { authService } from "fbase";
function App() {
//์ธ์ฆ์๋น์ค์ ํ์ฌ ์ ์ ๊ฐ ์ฐธ์ธ์ง ๊ฑฐ์ง์ธ์ง์ ๋ฐ๋ผ (๋ก๊ทธ์ธํ๋์ง ์ํ๋์ง์ ๋ฐ๋ผ)state ๋ฌ๋ผ์ง
const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
//๐ฅ ์ฒ์์ currentUser์ ๋ญ๋จ๋์ง ๋ณด์
console.log(authService.currentUser);
//๐ฅ 2์ด ๋ง๋ค currentUser๋ฅผ ์ฝ์์ ์ฐ์ด ๋ณด์
setInterval(() => {
console.log(authService.currentUser);
}, 2000);
//Router ๋ ๋ํ๊ธฐ
//AppRouter์ prop ์ ๋ฌํ๊ธฐ
return (
<>
<AppRouter isLoggedIn={isLoggedIn} />
<footer>© twinkle {new Date().getFullYear()}</footer>
</>
);
}
export default App;

๊ด์ฐฐ์๋ฅผ ์ฌ์ฉํด ์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ํ๋ฅผ ์ถ์ ํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ํ์ ๋ณํ๋ฅผ ๊ด์ฐฐํ๋ ๊ด์ฐฐ์์ด๋ค.
v.9์ ์ด ๋ฌธ์ ์ฐธ๊ณ
ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ฌ ๋ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ด Auth ๊ฐ์ฒด์ ๊ด์ฐฐ์๋ฅผ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.import { getAuth, onAuthStateChanged } from "firebase/auth"; // const auth = getAuth(); onAuthStateChanged(auth, (user) => { if (user) { // User is signed in, see docs for a list of available properties // https://firebase.google.com/docs/reference/js/firebase.User const uid = user.uid; // ... } else { // User is signed out // ... } });
- ๊ด์ฐฐ์๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ฌ ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ฌ ๋ Auth ๊ฐ์ฒด๊ฐ ์ค๊ฐ ๋จ๊ณ(์ด๊ธฐํ ๋ฑ)์ ์์ง ์๋๋ก ํ ์ ์๋ค. signInWithRedirect๋ฅผ ์ฌ์ฉํ๋ฉด
onAuthStateChanged๊ด์ฐฐ์๋ getRedirectResult๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ํ์ ํธ๋ฆฌ๊ฑฐ๋๋ค.
//์ ๋ ๊ฒฝ๋ก(absolute import)
import AppRouter from "components/Router";
import { useEffect, useState } from "react";
//์ ๋ ๊ฒฝ๋ก(absolute import)
//fbase์์ authService ๊ฐ์ ธ์ค๊ธฐ(export๋ก ๋ด๋ณด๋๊ธฐ ๋๋ฌธ์ {} ์ค๊ดํธ ์ณ์ ๊ฐ์ ธ์์ผ ํจ)
import { authService } from "fbase";
import { getAuth, onAuthStateChanged } from "firebase/auth";
function App() {
//๐ฅ firebase๊ฐ ํ๋ก๊ทธ๋จ์ ์ด๊ธฐํํ๊ธธ ๊ธฐ๋ค๋ฆฌ๊ณ ๋์ isLoggedIn์ด ๋ฐ๋๊ฒ ํด์ผ ํ๋ค.
const [init, setInit] = useState(false);
//์ธ์ฆ์๋น์ค์ ํ์ฌ ์ ์ ๊ฐ ์ฐธ์ธ์ง ๊ฑฐ์ง์ธ์ง์ ๋ฐ๋ผ (๋ก๊ทธ์ธํ๋์ง ์ํ๋์ง์ ๋ฐ๋ผ)state ๋ฌ๋ผ์ง
const [isLoggedIn, setIsLoggedIn] = useState(false);
//๐ฅ ์ด๋ป๊ฒ ๊ธฐ๋ค๋ฆด ์ ์์๊น? useEffect()๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค ใ
ใ
!
useEffect(() => {
const auth = getAuth();
//๐ฅ๐ฅ ์ ์ ๋ณํ๊ฐ ์๋์ง listenํ๊ธฐ: onAuthStateChanged๊ด์ฐฐ์ ์ฌ์ฉ
//๐ฅ onAuthStateChanged์ ์ฝ๋ฐฑ์ด ํ์ํ๋ฐ, ์ฝ๋ฐฑ์ user์ด๋ค.
onAuthStateChanged(auth, (user) => {
//console.log(user);
//๐ฅ user๊ฐ ์๋ค๋ฉด ๋ก๊ทธ์ธ ์ฐธ์ผ๋ก ๋ฐ๊ฟ์ฃผ๊ณ , ์๋๋ผ๋ฉด ๋ก๊ทธ์ธ ๊ฑฐ์ง์ผ๋ก
if (user) {
setIsLoggedIn(true);
const uid = user.uid;
} else {
setIsLoggedIn(false);
}
//๐ฅ ๊ทธ๋ฌ๊ณ ๋์ ์ด๊ธฐํ ์์ผ๋ผ
setInit(true);
});
}, []);
//Router ๋ ๋ํ๊ธฐ & AppRouter์ prop ์ ๋ฌํ๊ธฐ
return (
<>
{/*๐ฅ init์ด ๊ฑฐ์ง์ด๋ฉด ๋ผ์ฐํฐ ์จ๊ธฐ๊ณ ์ด๊ธฐํ ์ค์ด๋ผ๊ณ ๋์ฐ๊ธฐ*/}
{init ? <AppRouter isLoggedIn={isLoggedIn} /> : "์ด๊ธฐํ์ค..."}
<footer>© twinkle {new Date().getFullYear()}</footer>
</>
);
}
export default App;
์ค์ผ์ด
์ด๊ธฐํ์ค...๋ฌ๋ค์์ ๋ก๊ทธ์ธ ๋์์ผ๋ฉด HOME์ด ๋ฌ๋ค.
์ด์ ๋ก๊ทธ์์ํ์. indexedDB์ ์๋ data ์ง์ฐ๋ฉด ๋จ.
๊ณ์ ์ญ์ ํ๊ณ ์๋ก์ด ๊ณ์ ๋ง๋ค์.
๊ทธ๋ฌ๊ณ ๋์ ๋ ๋๊ฐ์ ๊ณ์ ์ ๋ง๋๋ ค๊ณ ํ๋ฉด ์ฝ์์ ์ค๋ฅ๊ฐ ๋ฌ๋ค.

email์ด ์ด๋ฏธ ์ฌ์ฉ ์ค์ด์ด์ ๋จ๋ ์ค๋ฅ์ธ๋ฐ, ์ด ๋ถ๋ถ์ ์ฌ๊ธฐ์ ๋ฐ์ํ๋ ์ค๋ฅ์ด๋ค.
๐ Auth.js
//๐ฅ ์ด๋ฉ์ผ, ๋น๋ฒ์ผ๋ก ์๋ก์ด ๊ณ์ ์์ฑ ๋ฐ ๋ก๊ทธ์ธ ํ๊ธฐ์ํด ์๋ ๋ฉ์๋ ์ํฌํธํ๊ธฐ
//๐ฅ getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
} from "firebase/auth";
import { useState } from "react";
const Auth = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [newAccount, setNewAccount] = useState(true);
const auth = getAuth();
//email, password์ ์ฌ์ฉํ๋ ์ด๋ฒคํธ
const onChange = (event) => {
const {
target: { name, value },
} = event;
if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
//form์ ์ฌ์ฉํ๋ ์ด๋ฒคํธ
const onSubmit = async (event) => {
event.preventDefault();
//form submitํ๋ฉด newAccount ์คํ
์ดํธ๋ก ํ์ธํ์!
//newAccount๊ฐ ์ฐธ์ด๋ฉด ๊ณ์ ์๋ก ๋ง๋ค๊ณ , ๊ฑฐ์ง์ด๋ฉด ๋ก๊ทธ์ธํ๊ธฐ
try {
let data;
if (newAccount) {
data = await createUserWithEmailAndPassword(auth, email, password);
setNewAccount(false);
} else {
data = await signInWithEmailAndPassword(auth, email, password);
}
console.log(data);
} catch (error) {
//โ๏ธโ๏ธโ๏ธโ๏ธโ๏ธโ๏ธ์ฌ๊ธฐ์์ ๋ฐ์ํ๋ ์๋ฌ!โ๏ธโ๏ธโ๏ธโ๏ธโ๏ธ
console.log(error);
}
};
return (
<div>
<h1>๋ก๊ทธ์ธ ํ์ด์ง</h1>
<p>๋ก๊ณ ๋ฃ๊ธฐ</p>
<form onSubmit={onSubmit}>
<input
type="email"
placeholder="Email"
required
value={email}
name="email"
onChange={onChange}
></input>
<input
type="password"
placeholder="Password"
required
value={password}
name="password"
onChange={onChange}
></input>
<input type="submit" value={newAccount ? "Create Account" : "Login"} />
</form>
<div>
<button>Continue with Google</button>
<button>Continue with GitHub</button>
</div>
</div>
);
};
export default Auth;
๋ฐ๋ผ์ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋์ฐ์.
//์ด๋ฉ์ผ, ๋น๋ฒ์ผ๋ก ์๋ก์ด ๊ณ์ ์์ฑ ๋ฐ ๋ก๊ทธ์ธ ํ๊ธฐ์ํด ์๋ ๋ฉ์๋ ์ํฌํธํ๊ธฐ
//getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
} from "firebase/auth";
import { useState } from "react";
const Auth = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [newAccount, setNewAccount] = useState(true);
//๐ฅ error ์คํ
์ด๋๋ฅผ ๋ง๋ค์. ๋ํดํธ ๊ฐ์ผ๋ก ๋น์ด ์๋ ํ
์คํธ ์ฃผ๊ธฐ
const [error, setError] = useState("");
const auth = getAuth();
//email, password์ ์ฌ์ฉํ๋ ์ด๋ฒคํธ
const onChange = (event) => {
const {
target: { name, value },
} = event;
if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
//form์ ์ฌ์ฉํ๋ ์ด๋ฒคํธ
const onSubmit = async (event) => {
event.preventDefault();
//form submitํ๋ฉด newAccount ์คํ
์ดํธ๋ก ํ์ธํ์!
//newAccount๊ฐ ์ฐธ์ด๋ฉด ๊ณ์ ์๋ก ๋ง๋ค๊ณ , ๊ฑฐ์ง์ด๋ฉด ๋ก๊ทธ์ธํ๊ธฐ
try {
let data;
if (newAccount) {
data = await createUserWithEmailAndPassword(auth, email, password);
setNewAccount(false);
} else {
data = await signInWithEmailAndPassword(auth, email, password);
}
console.log(data);
} catch (error) {
//๐ฅ์๋ฌ๊ฐ ์๊ธฐ๋ฉด error ์คํ
์ดํธ์ ๋ฃ์ด์ ์๋ฌ ๋ฉ์ธ์ง ๋์ฐ๊ธฐ
//console.log(error.message);
setError(error.message);
}
};
return (
<div>
<h1>๋ก๊ทธ์ธ ํ์ด์ง</h1>
<p>๋ก๊ณ ๋ฃ๊ธฐ</p>
<form onSubmit={onSubmit}>
<input
type="email"
placeholder="Email"
required
value={email}
name="email"
onChange={onChange}
></input>
<input
type="password"
placeholder="Password"
required
value={password}
name="password"
onChange={onChange}
></input>
<input type="submit" value={newAccount ? "Create Account" : "Login"} />
{/*๐ฅ error ๋ณด์ฌ์ฃผ๊ธฐ*/}
{error}
</form>
<div>
<button>Continue with Google</button>
<button>Continue with GitHub</button>
</div>
</div>
);
};
export default Auth;

//์ด๋ฉ์ผ, ๋น๋ฒ์ผ๋ก ์๋ก์ด ๊ณ์ ์์ฑ ๋ฐ ๋ก๊ทธ์ธ ํ๊ธฐ์ํด ์๋ ๋ฉ์๋ ์ํฌํธํ๊ธฐ
//getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
} from "firebase/auth";
import { useState } from "react";
const Auth = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [newAccount, setNewAccount] = useState(true);
//error ์คํ
์ด๋๋ฅผ ๋ง๋ค์. ๋ํดํธ ๊ฐ์ผ๋ก ๋น์ด ์๋ ํ
์คํธ ์ฃผ๊ธฐ
const [error, setError] = useState("");
const auth = getAuth();
//email, password์ ์ฌ์ฉํ๋ ์ด๋ฒคํธ
const onChange = (event) => {
const {
target: { name, value },
} = event;
if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
//form์ ์ฌ์ฉํ๋ ์ด๋ฒคํธ
const onSubmit = async (event) => {
event.preventDefault();
//form submitํ๋ฉด newAccount ์คํ
์ดํธ๋ก ํ์ธํ์!
//newAccount๊ฐ ์ฐธ์ด๋ฉด ๊ณ์ ์๋ก ๋ง๋ค๊ณ , ๊ฑฐ์ง์ด๋ฉด ๋ก๊ทธ์ธํ๊ธฐ
try {
let data;
if (newAccount) {
data = await createUserWithEmailAndPassword(auth, email, password);
setNewAccount(false);
} else {
data = await signInWithEmailAndPassword(auth, email, password);
}
console.log(data);
} catch (error) {
//์๋ฌ๊ฐ ์๊ธฐ๋ฉด error ์คํ
์ดํธ์ ๋ฃ์ด์ ์๋ฌ ๋ฉ์ธ์ง ๋์ฐ๊ธฐ
//console.log(error.message);
setError(error.message);
}
};
//๐ฅ ๊ฐ์
ํด์ผํ๋์ง ๋ก๊ทธ์ธํด์ผ ํ๋์ง ํ ๊ธํ๋ ํจ์: newAccount์ ์ด์ ๊ฐ๊ณผ ๋ฐ๋๋๋ ๊ฐ ๋ฆฌํดํ๊ธฐ
const toggleAccount = () => setNewAccount((prev) => !prev);
return (
<div>
<h1>๋ก๊ทธ์ธ ํ์ด์ง</h1>
<p>๋ก๊ณ ๋ฃ๊ธฐ</p>
<form onSubmit={onSubmit}>
<input
type="email"
placeholder="Email"
required
value={email}
name="email"
onChange={onChange}
></input>
<input
type="password"
placeholder="Password"
required
value={password}
name="password"
onChange={onChange}
></input>
<input type="submit" value={newAccount ? "๊ฐ์
ํ๊ธฐ" : "๋ก๊ทธ์ธ"} />
{/*error ๋ณด์ฌ์ฃผ๊ธฐ*/}
{error}
</form>
{/*๐ฅ newAccount(์๋ก์ด ๊ณ์ )๊ฐ ์ฐธ์ด๋ฉด ๋ก๊ทธ์ธ, ๊ฑฐ์ง์ด๋ฉด ๊ฐ์
ํ๊ธฐ๊ฐ ๋๋ ํ ๊ธ ๋ง๋ค๊ธฐ */}
<button onClick={toggleAccount}>
{newAccount ? "๋ก๊ทธ์ธ" : "๊ฐ์
ํ๊ธฐ"}
</button>
<div>
<button>Continue with Google</button>
<button>Continue with GitHub</button>
</div>
</div>
);
};
export default Auth;