투두리스트 UI을 거의 전부 완성하였다. 시간이 오래 걸리긴 했지만 공부했던 개념들을 실전에 적용시키면서 실용적인 공부를 한것 같다.
Firebase 시작
Firebase에 회원가입, 로그인 후 프로젝트 생성
firebase sdk 추가(내 앱과 연동하는 과정)
npm install firebase
데이터베이스 사용하기 (firestore)
import { initializeApp } from "firebase/app";
import { getFireStore } from "firebase/firestore";
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxxxx",
projectId: "xxxxxxxxx",
storageBucket: "xxxxxxxx",
messagingSenderId: "xxxxxxxx",
appId: "xxxxxxxx",
};
const app = initializeApp(firebaseConfig);
export const firestore = getFireStore(app);
입력폼으로 submit하여 firestore에 데이터 전송해보기
적당한 페이지에(리액트라면 app.js등) 입력 폼을 만든다.
function App() {
const messageRef = useRef();
const handleSave = async (e) => {
e.preventDefault();
console.log(messageRef.current.value);
};
return (
<form onSubmit={handleSave}>
<label for="data">Enter message</label>
<input id="data" type="text" ref={messageRef} />
<button type="submit">Save</button>
</form>
);
}
export default App;
firestore관련 메서드들을 import해온다.
import { firestore } from "./service/firebase";
import { addDoc, collection } from "firebase/firestore";
function App() {
const messageRef = useRef();
const handleSave = async (e) => {
e.preventDefault();
console.log(messageRef.current.value);
};
return (
<form onSubmit={handleSave}>
<label for="data">Enter message</label>
<input id="data" type="text" ref={messageRef} />
<button type="submit">Save</button>
</form>
);
}
export default App;
collection 메서드를 통해 firestore에 대한 특정 collection 레퍼런스를 가져온다.
collection은 firestore의 db 테이블과 같은것이라고 이해했다. 예를 들어 todo item 테이블에 아이템을 추가하고 싶으면 collection이름이 todo-item처럼 넣으면 된다. collection메서드는 이 테이블에 대한 레퍼런스를 가져오는 메서드인듯하다. collection을 추가한다.
import { firestore } from "./service/firebase";
import { addDoc, collection } from "@firebase/firestore";
function App() {
const messageRef = useRef();
***const ref = collection(firestore, "messages");***
const handleSave = async (e) => {
e.preventDefault();
console.log(messageRef.current.value);
};
return (
<form onSubmit={handleSave}>
<label for="data">Enter message</label>
<input id="data" type="text" ref={messageRef} />
<button type="submit">Save</button>
</form>
);
}
export default App;
addDoc메서드를 사용하여 우리가 만든 collection에 대한 레퍼런스(ref)와 보낼 데이터를 인자로 각각 넘겨 호출한다.
addDoc(콜렉션에 대한 레퍼런스, 보낼 데이터);
const handleSave = async (e) => {
e.preventDefault();
console.log(messageRef.current.value);
try {
let data = {
message: messageRef.current.value,
};
addDoc(ref, data);
} catch (e) {
console.error(e);
}
};
데이터 조회하기
const handleGetData = async (e) => {
const querySnapshot = await getDocs(ref);
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data().message}`);
});
};
위와 같이 getDocs를 통해 해당 컬렉션의 모든 데이터를 가져올 수 있다.
collection안에 추가된 데이터들을 documents(문서)라고 부른다. 위 사진에서 document의 id가 두 번째 컬럼에 보이는 랜덤 제네레이션된 값이고, doc.id로 접근가능하다. 우리가 테스트한 message는 doc.data().message로 접근 가능하다.
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
**import { getAuth } from "firebase/auth";**
const firebaseConfig = {
apiKey: "xxxxxcxxxxxxxxxx",
authDomain: "xxxxxxxxxx",
projectId: "xxxxxxxx",
storageBucket: "txxxxxxxx",
messagingSenderId: "4xxxxxxx",
appId: "xxxxxxxxx",
};
const app = initializeApp(firebaseConfig);
**export const firebaseAuth = getAuth(app);**
export const firestore = getFirestore(app);
**import { onAuthStateChanged } from "firebase/auth";**
useEffect(() => {
**onAuthStateChanged**(firebaseAuth, async (user) => {
if (user) {
const q = query(
collection(firestore, "users"),
where("uid", "==", user.uid)
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
const data = doc.data();
setUserInfo({
uid: data.uid,
email: data.email,
displayName: data.displayName,
date_created: data.date_created,
});
});
setIsLoggedIn(true);
}
});
}, []);
const handleSignin = async (e) => {
e.preventDefault();
await **signInWithEmailAndPassword**(firebaseAuth, input.email, input.password)
.then(() => {
navigate("/");
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.warn(`${errorCode} = ${errorMessage}`);
});
};
로그인, 회원가입을 구현할 때 처음에 많이 헤매서 시간을 잡아먹었다. 프로젝트에 집중한 나머지 면접스터디를 조금 소홀히 한 것 같다.