안내에 따라 Firebase를 웹 앱에 추가합니다.
Cloud Firestore SDK는 npm 패키지로 제공됩니다.Firebase와 Cloud Firestore를 모두 가져와야 합니다.
npm install firebase@9.9.1 --save
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
// TODO: Replace the following with your app's Firebase project configuration
// See: https://firebase.google.com/docs/web/learn-more#config-object
const firebaseConfig = {
// ...
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore(app);
form
태그와 input
태그로 데이터 저장 form을 작성합니다.// CURD 게시판 구현
import React, { useState } from 'react'
const Home = () => {
const [content, setContent] = useState("");
const onChange = (e) => {
const { target: { vlaue } } = e;
setContent(vlaue);
}
const onSubmit = () => {
e.preventDefault();
}
return (
<div>
{/* Create : 데이터를 받아 저장할 form */}
<form onSubmit={onSubmit}>
<input
type="text"
placeholder="입력해주세요."
onChange={onChange}
value={content}
maxLength={120} />
<input
type="submit"
value="SNS" />
</form>
{/* Read : 저장된 데이터를 보여줄 div */}
<div>
</div>
</div>
)
}
export default Home
// original 코드
import { collection, addDoc } from "firebase/firestore";
try {
const docRef = await addDoc(collection(db, "users"), {
first: "Ada",
last: "Lovelace",
born: 1815
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
firebase
는 기본적으로 비동기적으로 동작합니다.addDoc, collection
이 동작할 때까지 기다리기 위해 async/await
로 비동기처리를 합니다.fbInstance
에서 미리 만든 dbService를 불러옵니다.dbService는 collection
의 매개변수로 담습니다.
// 수정한 코드
import { collection, addDoc } from "firebase/firestore";
import { dbService } from '../firebase/fbInstance';
const Home = () => {
const [content, setContent] = useState("");
const onChange = (e) => {
const { target: { value } } = e;
setContent(value);
}
const onSubmit = async (e) => {
e.preventDefault();
await addDoc(collection(dbService, "contents"), {
text: content,
createdAt: Date.now()
});
setContent("");
}
...
}
get
메서드를 사용해 전체 컬렉션을 가져올 수도 있습니다.// original 코드
import { collection, getDocs } from "firebase/firestore";
const querySnapshot = await getDocs(collection(db, "users"));
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
});
// 수정한 코드
import React, { useEffect, useState } from 'react'
import { collection, addDoc, getDocs } from "firebase/firestore";
import { dbService } from '../firebase/fbInstance';
const Home = () => {
const [content, setContent] = useState("");
const [contents, setContents] = useState([]);
const getContents = async () => {
const q = query(collection(dbService, "contents"));
const dbContents = await getDocs(q);
dbContents.forEach((doc) => {
const contentObject = {
...doc.data(),
id: doc.id,
}
setContents(prev => [contentObject, ...prev]);
});
};
...
}
onSnapshot()
메서드로 문서를 수신 대기 할 수 있습니다.// original 코드
import { doc, onSnapshot } from "firebase/firestore";
const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => {
console.log("Current data: ", doc.data());
});
get()
대신 onSnapshot()
을 사용하여 쿼리 결과를 수신 대기할 수 있습니다.// original 코드
import { collection, query, where, onSnapshot } from "firebase/firestore";
const q = query(collection(db, "cities"), where("state", "==", "CA"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const cities = [];
querySnapshot.forEach((doc) => {
cities.push(doc.data().name);
});
console.log("Current cities in CA: ", cities.join(", "));
});
onSnapshot
으로 불러온 데이터를 contentsArr
에 다시 담고, setContents에 업데이트 합니다.[doc.id](http://doc.id)
값을 id 값으로 넣습니다.// 수정한 코드
import { collection, addDoc, onSnapshot, query, orderBy } from "firebase/firestore";
const getData = () => {
const q = query(
collection(dbService, "contents"),
orderBy("createdAt", "desc")
);
onSnapshot(q, (collections) => {
const contentsArr = collections.docs.map((doc) => (
{
id: doc.id,
...doc.data(),
}
))
setContents(contentsArr);
});
}
toggleEditing
메소드가 실행되어 editing state
의 false 값을 true로 바꿉니다.editing
값이 true이면 text 수정이 가능한 form 태그가 나오고, false이면 수정 전 text와 수정이 가능한 수정 버튼이 나오도록 합니다.import React, { useState } from 'react'
const Content = ({ contentObj }) => {
const [editing, setEditing] = useState(false);
const [newContent, setNewContent] = useState(contentObj.text)
const toggleEditing = () => setEditing((prev) => !(prev))
const onChange = (e) => {
const {target : {name, value}} = e;
setNewContent(value);
}
const onSubmit = (e) => {
e.preventDefault();
}
return (
<>
{editing ? (
<form onSubmit={onSubmit}>
<input
onChange={onChange}
type="text"
placeholder="텍스트 수정"
value={newContent}
required />
<input
type="submit"
value="수정"/>
<button onClick={toggleEditing}> 취소 </button>
</form>
) : (
<div>
<h4>{contentObj.text}</h4>
<button>삭제</button>
<button onClick={toggleEditing}>수정</button>
</div >
)
}
</>
)
}
export default Content
update()
메서드를 사용합니다.// original 코드
import { doc, updateDoc } from "firebase/firestore";
const washingtonRef = doc(db, "cities", "DC");
// Set the "capital" field of the city 'DC'
await updateDoc(washingtonRef, {
capital: true
});
// 수정한 코드
import { doc, updateDoc } from "firebase/firestore";
import { dbService } from '../firebase/fbInstance';
const onSubmit = (e) => {
e.preventDefault();
const updateRef = doc(dbService, "contents", contentObj.id);
updateDoc(updateRef, {
text: newContent
});
setEditing(false);
}
delete()
메서드를 사용합니다.import { doc, deleteDoc } from "firebase/firestore";
await deleteDoc(doc(db, "cities", "DC"));