예전에 진행한 프로젝트에서 직접적으로 활용해보지 못한 Firebase 활용 및 학습 목적의 프로젝트로 수입 및 지출 내역을 입력하면 총 내역 및 세부 지출 내역의 정보를 차트로 시각화한 서비스를 진행 했습니다.
먼저 Firebase를 활용해 보는 학습 목적을 가지고 있으므로 구글 계정을 통한 로그인부터 데이터 생성, 가져오기, 삭제를 마치고 이에 대한 hosting 배포의 과정을 생각하며 시작했습니다.
활용한 기능
// useGetDoc
const useGetDoc = (uid: string, type: string | null) => {
const [docList, setDocList] = useState<docType[]>([]);
useEffect(() => {
const userDiary = `user/${uid}/user-diary`;
let unsubscribe: Unsubscribe;
// 내역 button 필터링
if (type === "수입" || type === "지출") {
const queryCheck = query(collection(db, userDiary), where("type", "==", type), orderBy("date", "desc"));
unsubscribe = onSnapshot(queryCheck, (snapShot) => {
const productArr = snapShot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as docType));
setDocList(productArr);
});
} else {
// 전체 내역 필터링
const queryCheck = query(collection(db, userDiary), orderBy("date", "desc"));
unsubscribe = onSnapshot(queryCheck, (snapShot) => {
const productArr = snapShot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as docType));
setDocList(productArr);
});
}
// 메모리 누수를 방지 및 불필요한 서버 리소스 줄이기 위해 onSnapshot 구독 해제
return () => {
if (unsubscribe) {
unsubscribe();
}
};
}, [uid, type]);
// 내역별 총 계산
const typeCheck = useMemo(() => docList.filter((item) => item.type === type), [docList]);
const onlyNumberPrice = useMemo(() => typeCheck.map((item) => item.price.replace(/[^\d]/g, "")), [typeCheck]);
const total = useMemo(() => onlyNumberPrice.reduce((acc, el) => acc + Number(el), 0), [onlyNumberPrice]);
return { docList, total };
};