[Firebase] 새 버전(ver.9)으로 CRUD 구현하기

Tai Song·2022년 7월 28일
3

T-I-L

목록 보기
1/2
post-thumbnail

기본적인 CRUD와 Auth 기능이 있는 미니 프로젝트를 시작하기로 하고, 프론트엔드는 리액트, 서버와 데이터베이스는 파이어베이스로 구현하기로 했다.

내가 Firebase를 선택한 이유

  • 백엔드 없이 Auth, oAuth, Database를 전부 구현할 수 있다!
  • 애용하는 루틴 앱이 파이어베이스 DB를 쓴다
  • 전 회사에서 개발자 마케터 구분 없이 파이어베이스를 애용했다

👉 파이어베이스는 백엔드 개발자가 없는 미니 프로젝트에 쓰기에는 적합하지만, 유저와 DB가 증가할 수록 지불 비용이 커지고 파이어베이스에서 제공하는 제한된 기능만 사용할 수 있다는 점에서 복잡하고 큰 프로젝트에는 잘 맞지 않을 가능성이 크다.

파이어베이스의 기초를 다지기 위해서 먼저 노마드코더의 트위터 클론 강의를 수강했다. 무료였고, 강의 전체에서 파이어베이스 분량은 1시간 내외로 짧았기 때문이다. 강의로는 대략 감만 잡고 공식 문서로 나머지를 채우는 것이 목표였다.

강의를 들으면서 알게 된 점은, 파이어베이스 버전이 최근에 업데이트 되어 온라인 레퍼런스를 참고하기 어렵다는 사실이었다. 노마드코더 강의도 마찬가지로 지난 버전을 설명하고 있었는데, 새 버전에서는 근본적인 임포트 방법부터 작은 부분의 메서드까지 모조리 변경되어 참고하는 것이 불가능한 수준이었다.

👉 새로운 언어나 라이브러리를 배울 때는 강의를 먼저 듣는 것이 아니라 공식 문서로 먼저 공부한 뒤, 모자란 부분만 레퍼런스를 참고하는 것이 좋다는 깨달음을 얻었다.

참고서나 학습지를 먼저 풀고 교과서를 읽지 않듯이, 개발에 있어서도 공식 문서를 존중하고 가장 먼저 이해하려는 태도가 필요하다. 그래서 이 포스트를 읽는 분들도, 프로젝트에 Firebase를 적용할 예정이라면 공식 문서를 훑고 오면 큰 도움이 될 것 같다 :)

Firebase 기본 세팅

1. 프로젝트에 Firebase 설치하기

npm install firebase

파이어베이스에 가입하고 새 프로젝트를 만들었다면, 먼저 firebase를 적용할 레포지토리에 파이어베이스 패키지를 설치한다.

2. Firebase config 파일 만들기

해당 레포지토리에 myBase.js나 firebaseInstance.js나 firebaseConfig.js나... 원하는 이름으로 js 파일을 만들어, 내 파이어베이스의 config 코드를 작성한다.

config 파일의 내용은 콘솔 > 해당 프로젝트 > 프로젝트 설정에서 확인할 수 있다.

import { initializeApp } from "firebase/app";
/* 앱 초기화를 위한 import */
import { getFirestore } from "firebase/firestore";
/* 데이터베이스(firestore) 사용을 위한 import */


const firebaseConfig = {
  apiKey: process.env.REACT_APP_APIKEY,
  authDomain: process.env.REACT_APP_AUTHDOMAIN,
  projectId: process.env.REACT_APP_PROJECTID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGINGSENDERID,
  appId: process.env.REACT_APP_APPID,
  measurementId: process.env.REACT_APP_MEASUREMENTID
};

export const app = initializeApp(firebaseConfig);
export const db = getFirestore(app)
/* 이제 다른 js 파일에서 firestore db를 불러올 수 있다 */

config 파일은 내 파이어베이스 프로젝트의 API key나, authDomain 등을 저장하고, 해당 정보로 firebase 메서드를 초기화하기 위한 것. 마지막 줄에 원하는 이름의 변수로 파이어베이스 앱을 초기화해 export 시켜주면, 다른 js 파일에서 불러와 다양한 메서드를 사용할 수 있게 된다.

apiKey나 authDomain 등이 github으로 업로드 되지 않게 하기 위해서는, 해당 정보들을 .env 파일에 환경 변수로 저장해두고 .gitignore에 추가한 뒤 여기서는 process.env.으로 불러와주자.

👉 환경변수 .env 설정법

Firestore로 데이터 관리하기

1. 데이터 생성하기(Create) 공식 문서

import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { collection, addDoc } from "firebase/firestore";

try {
  const docRef = await addDoc(collection(db, "users"), {
    /* users라는 객체에 아래 데이터가 담기게 된다 */
    first: "Ada",
    last: "Lovelace",
    born: 1815
  });
  console.log("Document written with ID: ", docRef.id);
} catch (e) {
  console.error("Error adding document: ", e);
}

이렇게 생성된 데이터는 콘솔에서 바로 확인하고 관리할 수 있다는 점이 파이어베이스의 장점이기도 하다.

2. 데이터 불러오기(Read) 공식 문서

  • 컬렉션의 모든 문서 가져오기
import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { collection, getDocs } from "firebase/firestore";

const querySnapshot = await getDocs(collection(db, "cities"));
/* cities라는 컬렉션의 모든 문서를 담는 변수 */
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
  /* 이 부분에서 console.log 대신 setState()를 이용해 원하는 변수에 담아주면 된다. */
});
  • 컬렉션의 특정 문서 가져오기
import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { doc, getDoc } from "firebase/firestore";

const docRef = doc(db, "cities", "SF");
/* cities라는 문서에 SF라는 필드의 주소값을 담기 */
const docSnap = await getDoc(docRef);
/* SF라는 필드의 데이터를 담기 */

if (docSnap.exists()) {
  console.log("Document data:", docSnap.data());
} else {
  // doc.data() will be undefined in this case
  console.log("No such document!");
}
  • 컬렉션에서 조건에 맞는 문서들만 가져오기
import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { collection, query, where, getDocs } from "firebase/firestore";

const q = query(collection(db, "cities"), where("capital", "==", true));
/* cities라는 컬렉션의 문서 중 capital이라는 key의 값이 true인 문서들만 담기 */

const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
});
  • 실시간 데이터 받아오기

SNS에서 게시물을 작성하는 즉시 리스트에 새로운 게시물이 생기는 것처럼, 라이브로 데이터를 받아오고 싶다면 onSnapshot 메서드를 사용한다.

import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { collection, query, where, onSnapshot } from "firebase/firestore";

const q = query(collection(db, "cities"), where("state", "==", "CA"));
/* cities 컬렉션에서 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(", "));
});

3. 데이터 수정하기(Update) 공식문서

import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { doc, updateDoc } from "firebase/firestore";

const washingtonRef = doc(db, "cities", "DC");

// "DC" 문서의 capital 필드(키) 값 수정하기
await updateDoc(washingtonRef, {
  capital: true
});

4. 데이터 삭제하기(Delete) 공식문서

  • 문서 삭제하기
import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { doc, deleteDoc } from "firebase/firestore";

await deleteDoc(doc(db, "cities", "DC"));
  • 문서에서 특정 필드 삭제하기
import db from "./firebaseConfig.js";
/* db를 내보낸 경로에서 db도 import 해주어야 한다 */
import { doc, updateDoc, deleteField } from "firebase/firestore";

const cityRef = doc(db, 'cities', 'BJ');

// 문서에서 'capital'이라는 필드(키)를 삭제한다
await updateDoc(cityRef, {
    capital: deleteField()
});
profile
Read The Fucking MDN

0개의 댓글