→ 나는 웹에서 사용할 것이므로 </>
아이콘을 클릭했다.
.env
를 이용하여 환경변수로 작성해주었다.import { initializeApp } from 'firebase/app';
const firebaseConfig = {
apiKey: process.env.REACT_APP_APIKEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
measurementId: process.env.REACT_APP_MEASUREMENT_ID,
databaseURL: process.env.REACT_APP_DATABASE_URL,
};
const app = initializeApp(firebaseConfig);
src / firebase / firebase.ts
에 작성해주었다.Firestore
를 사용하여 데이터 베이스를 연결해보고자 한다.실시간 데이터베이스
와 파이어스토어 데이터베이스
가 있다.firebase.ts
파일에 아래의 코드를 추가했다.import { getFirestore } from 'firebase/firestore';
// ... 기존내용
const firestore = getFirestore(app);
export const firebaseDB = firestore;
firebaseDB
라는 이름으로 내보내어 db에 접근 할 수 있게 됐다.DBHandler
라는 파일을 만들어 객체 형식으로 메소드를 관리를 하기로 했다.import {
collection,
deleteDoc,
doc,
getDocs,
setDoc,
} from 'firebase/firestore';
import { firebaseDB } from './firebase';
// collection(db, 'collectionPath') 가 접근하고자 하는 db 와 컬렉션의 주소를 가짐
// REST API 를 기준으로 하자면, URI 의 역할을 하는 것.
const DBHandler = {
async readPost(ref: string) {
const snapshot = await getDocs(collection(firebaseDB, ref));
return snapshot.docs.map((doc) => {
return Object.assign(doc.data(), {id : doc.id});
})
},
async writePost(
ref: string,
data: { nickname: string; content: string; userId: string }
) {
await setDoc(doc(collection(firebaseDB, ref)), {
nickname: data.nickname,
content: data.content,
userId: data.userId,
timestamp: serverTimestamp(),
comments: [],
});
},
async deletePost(id: string) {
deleteDoc(doc(firebaseDB, `posts/${id}`));
},
async writeComment(id: string, data: { comment: string; userId: string }) {
await updateDoc(doc(firebaseDB, `posts/${id}`), {
comments: arrayUnion({ content: data.comment, userId: data.userId }),
});
},
async deleteComment(id: string, data: { comment: string; userId: string }) {
await updateDoc(doc(firebaseDB, `posts/${id}`), {
comments: arrayRemove({ content: data.comment, userId: data.userId }),
});
},
};
export default DBHandler;
getDocs()
setDoc()
/ addDoc()
updateDoc()
deleteDoc()
getDoc()
메소드를 사용한다. async readPost(ref: string) {
const snapshot = await getDocs(collection(firebaseDB, ref));
return snapshot.docs.map((doc) => {
return Object.assign(doc.data(), {id : doc.id});
})
},
collection(db, collectionPath)
를 이용하여 원하는 콜렉션의 참조값을 저장하고, 해당 참조값을 getDocs()
에 전달한다.getDocs()
이 반환하는 값은 프라미스 객체이며, 해당 객체에 docs
프로퍼티를 사용하여 배열의 형태로 컬렉션 내부의 데이터 객체를 받을 수 있다.data()
메소드를 이용하면 우리가 직접적으로 데이터를 꺼내 쓸 수 있는 객체의 형태가 된다.onSnapshot()
을 이용하여 서버의 변경을 감지 할 수 있다고 하여 사용했다.DBHandler
에 추가하지 않고, App 컴포넌트에 직접 작성해주었다.// App.tsx
const [posts, setPosts] = useState<any[]>([]);
// 서비스 제작보단 파이어베이스 경험이 우선이다보니 any 타입이 좀 많다.
useEffect(() => {
onSnapshot(collection(firebaseDB, 'posts'), (snapshot) => {
const postsArr = snapshot.docs.map((eachDoc) => {
return Object.assign(eachDoc.data(), { id: eachDoc.id });
});
const sortedArr = postsArr.sort((a: any, b: any) => {
return b.timestamp - a.timestamp;
});
setPosts(sortedArr);
});
onSnapshot(collectionRef, callback)
으로 사용하며, 콜백함수의 매개변수로 snapshot
을 이용 할 수 있다.collectionRef
== collection(db, collectionPath)
getDocs()
의 snapshot
과는 다르게 프라미스 객체를 반환하지 않으며, 바로 docs
프로퍼티를 사용 할 수 있다.getDocs()
의 경우 async/await 문법이 아니면 docs
에 접근 할 수 없다.setDoc()
메소드를 사용한다. async writePost(
ref: string,
data: { nickname: string; content: string; userId: string }
) {
await setDoc(doc(collection(firebaseDB, ref)), {
nickname: data.nickname,
content: data.content,
userId: data.userId,
timestamp: serverTimestamp(),
comments: [],
});
},
setDoc(doc(collectionRef), data, data_id)
로 원하는 컬렉션에 원하는 id 를 설정하여 데이터를 추가 할 수 있다.addDoc()
을 사용 할 수 있다.addDoc()
을 사용한 경우의 코드는 아래와 같다. async writePost(
ref: string,
data: { nickname: string; content: string; userId: string }
) {
await addDoc(collection(firebaseDB, ref), {
nickname: data.nickname,
content: data.content,
userId: data.userId,
timestamp: serverTimestamp(),
comments: [],
});
},
doc()
이 사용되지 않고, 바로 컬렉션과 데이터만 전달한다.해당 컬렉션 주소의 문서
가 메인이 되는가 혹은, 컬렉션
이 메인이 되는가 의 차이이지 않을까 추측해본다.deleteDoc()
을 이용한다.async deletePost(id: string) {
deleteDoc(doc(firebaseDB, `posts/${id}`));
},
doc()
의 인자로 작성하여 전달하면 된다.updateDoc()
을 사용한다.async updatePostContent(id:string, content : string){
updateDoc(doc(firebaseDB, `posts/${id}`),{
content
})
},
deleteDoc()
과 상당히 유사하며, 수정하고자 하는 필드와 변경하고자 하는 데이터를 전달하면 된다.참고 블로그
https://velog.io/@wiostz98kr/Firebase-Realtime-Databasehttps://velog.io/@dev-hannahk/react-firebase-crud
https://velog.io/@seondal/Firebase-v9부터-달라진-인증모듈-사용법