Firebase ์์ํ๊ธฐ
์ค์น
npm install --save firebase
firebase๋ฅผ ์ค์นํ๋ ๋ฐฉ๋ฒ์ ๋ค์ํ๋ค. ๋๋ Node.js ๊ธฐ๋ฐ์ผ๋ก ์์ํ๊ธฐ์ ์์ ๊ฐ์ด ํ๋ก์ ํธ์ firebase๋ฅผ ์ค์นํ๋ค.
์
ํ
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
var firebaseConfig = {
//... configuration
};
firebase.initializeApp(firebaseConfig); // Initialize
firebase๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์์ ๊ฐ์ด ํ์ํ ๊ธฐ๋ฅ(๋์ ๊ฒฝ์ฐ auth์ firestore)์ importํ๊ณ , firebase ์ฑ์ ๋ง๋ค๋ฉด ์ ๊ณต๋๋ configuration์ ์ ๋ ฅํ ํ ์ด๊ธฐํ ํด์ค๋ค.
export const firebaseInstance = firebase;
export const authService = firebase.auth();
export const dbService = firebase.firestore();
๋ํ ๋๋ firebase ๊ด๋ จ ์ฝ๋๋ฅผ ๋ณ๋์ ํ์ผ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์, ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ firebase๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก exportํ๋ค.
์ธ์ฆ ๊ธฐ๋ฅ
import { authService, firebaseInstance } from '../fbase.js';
์ ํ ์์ exportํ firebaseInstance์ authService๋ฅผ import ํด์ค๋ค.
const onLoginClick = async (event) => {
const {
target: { name },
} = event;
const provider = new firebaseInstance.auth.GoogleAuthProvider();
await authService.signInWithRedirect(provider);
};
const onLogOutClick = async () => {
await authService.signOut();
};
๋๋ ๊ตฌ๊ธ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ๋ง ์ฌ์ฉํ๋ค. ์ ์ ํ ์ปดํฌ๋ํธ(๋ก๊ทธ์ธ ๋ฒํผ)์ onClick={onLoginClick} ์์ฑ์ ์ ์ฉํ๋ฉด ๊ตฌ๊ธ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ ๋! (๋ก๊ทธ์์๋ ๋ง์ฐฌ๊ฐ์ง)
์ด ๋, async/await์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ/๋ก๊ทธ์์์ ๋น๋๊ธฐ๋ก ์งํ๋๋๋ก ์ฒ๋ฆฌํ๋ค.
DB (firestore)
import { authService, dbService } from '../fbase.js';
authService์ dbService๋ฅผ import ํ๋ค.
๋ฐ์ดํฐ ์
๋ ฅ
onSubmit = async (event) => {
event.preventDefault();
await dbService.collection(authService.currentUser.uid).add({
info: this.state,
createdTime: Date.now(),
createdName: authService.currentUser.displayName,
});
์ ์ ํ ์ปดํฌ๋ํธ์ onSubmit={onSubmit} ์์ฑ์ ์ ์ฉํด์ฃผ๋ฉด ๋๋ค.
์ฐธ๊ณ ๋ก firestore๋ noSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก, collection์์ ์ฌ๋ฌ ๊ฐ์ doc๋ค์ด ์์นํ๊ณ , ๊ฐ๊ฐ์ doc๋ค์ ์ฌ๋ฌ ๊ฐ์ key:value ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์์ด๋ค. (collection ํด๋ ์์ doc๋ค์ด ์๋ ๊ฒ๊ณผ ๋น์ท)
๋์ ๊ฒฝ์ฐ collection์ ์ด๋ฆ์ ๋ก๊ทธ์ธํ ์ ์ ์ uid ์์ฑ์ผ๋ก ์ค์ ํ๋ค. ์ฐธ๊ณ ๋ก doc์ ์ด๋ฆ์ firestore๊ฐ ๋๋ค์ผ๋ก ์์ฑํด์ค๋ค.
๋ด๊ฐ ์
๋ ฅํ ์ ๋ณด๋ ์ ๋ณด์ ์
๋ ฅ ์์ (createdTime: Date.now()), ์์ฑ์์ ์ด๋ฆ(createdName: authService.currentUser.displayName : ๋์ ๊ฒฝ์ฐ ๊ตฌ๊ธ ๊ณ์ ์ ์ค์ ๋ ์ด๋ฆ)๊ณผ info(this.state : ๊ฐ์ฒด๋ก ์ฐ์ฌ์ง ์ฌ๋ฌ ์ ๋ณด๋ค)๋ค.
๋ฐ์ดํฐ ์ถ๋ ฅ
useEffect(() => {
dbService.collection(authService.currentUser.uid).orderBy("createdTime", "desc").onSnapshot((snapshot) => {
const problemArray = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setProblems(problemArray);
});
}, []);
React Hooks๋ฅผ ์ด์ฉํ์๋ค.
์ถ๋ ฅํ๋ ค๋ ๋ฐ์ดํฐ์ collection ์ด๋ฆ(๋์ ๊ฒฝ์ฐ authService.currentUser.uid์ collection ๋ฉ์๋์ ์ธ์๋ก ์ค๋ค. orderBy("createdTime", "desc")๋ก ํด๋น collection์ docs๋ค์ createdTime์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ค. ์ดํ onSnapshot์ ์ด์ฉํด problemArray์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์ problem hook์ ์ ์ฅํ๋ค.
์ด ๋, doc.id๋ ๋ฐ์ดํฐ ์
๋ ฅ์ ์์๋ก ์์ฑ๋ doc์ ์ด๋ฆ์ด๋ค. ์ฐธ๊ณ ๋ก onSnapshot์ ์ด์ฉํ๋ฉด firestore์ ๋ณํ๊ฐ ๋ฐ์ํ๋ฉด ์ค์๊ฐ์ผ๋ก ์ถ๋ ฅ ๊ฒฐ๊ณผ๊ฐ ์
๋ฐ์ดํธ๋๋ค.
๋ฐ์ดํฐ ์ญ์
const onDeleteClick = async (problem) => {
const ok = window.confirm('์ ๋ง ์ญ์ ํ์๊ฒ ์ต๋๊น??');
if (ok) {
await dbService.doc(`${authService.currentUser.uid}/${problem.id}`).delete();
}
};
์ ์ ํ ์ปดํฌ๋ํธ์ onClick={onDeleteClick} ์์ฑ์ ์ฃผ๋ฉด ์ํ๋ docs๋ฅผ ์ญ์ ํ ์ ์๋ค.
์ด๋ doc์ ์ธ์๋ (collectionName/docId)์ผ ํ๋ค. ๋์ ๊ฒฝ์ฐ collection์ ์ด๋ฆ์ authService.currentUser.uid์ด๊ณ , doc์ ์ด๋ฆ์ problem.id๋ก ๋ฐ์์๋ค.
async resetData() {
if (window.confirm('์ ๋ง ์ด๊ธฐํ ํ์๊ฒ ์ต๋๊น?\n์
๋ ฅํ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ญ์ ๋ฉ๋๋ค.')) {
await dbService
.collection(authService.currentUser.uid)
.get()
.then((res) => {
res.forEach((element) => {
element.ref.delete();
});
});
}
}
ํ collection์ ๋ชจ๋ docs๋ฅผ ํ๋ฒ์ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต๋์ง ์๋ ๊ฒ ๊ฐ๋ค. ์์ ๊ฐ์ด resetData ํจ์๋ฅผ ์์ฑํด์ ์ฌ์ฉํ๋ฉด ๋๋ค.
https://velog.io/@dojunggeun/Firebase-%EC%9D%B8%EC%A6%9D-Firestore