Just Do IT!

[React Native] react native 프로젝트와 firebase 연동하기 본문

개발 공부/React Native

[React Native] react native 프로젝트와 firebase 연동하기

MOON달 2023. 1. 2. 15:57
728x90
반응형
firebase 연동하기

지난주에는 asyncstorage를 이용했었다면, 이번에는 firebase를 연동해서 투두리스트를 만드는 강의를 들었다.

처음에는 뭔가 오류가 계속 났는데 공식 문서도 보고 오타도(ㅎ) 고쳐보니 잘 연동되고 신기한 경험이었다.

나중에 프로젝트 때도 유용할 것 같아서 블로그에도 미리 남겨둔다.

 

 

 

 

 

 

firebase 설치하기
npm instsall firebase --save

터미널에 위 명령어 입력해서 react native 프로젝트에 firebase 패키지를 설치한다.

 

 

 

 

 

firebase.js 파일 만들기 (firebase 연동)

미리 firebase에서 프로젝트를 생성하고 프로젝트를 생성함에 따라 나오는 SDK 설정을 연동해야 한다.

 

이 부분을 연동해야 firebase와 연동된다

 

// firebase.js

import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

// 아래 데이터는 본인의 Firebase 프로젝트 설정에서 확인할 수 있습니다.
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
};

// Initialize Firebase
export const app = initializeApp(firebaseConfig);
export const dbService = getFirestore(app);

 

 

 

 

 

CRUD (todolist에서 사용한 부분)

튜터님이 제공해주신 강의 자료에도 적혀있는데, 내 블로그에도 적어본다.

처음에는 뭐가 어떤 식으로 쓰이는 지 잘 이해가 안되다가 예전 프로젝트에서 firebase 연동해서 사용했던 게 생각났다.

그때 코드를 다시 살펴보니까 비슷한 것 같기도 하고...? 그 때 공부 좀 열심히 할걸...ㅋㅋㅋㅋ

 

import {
  onSnapshot,
  query,
  collection,
  doc,
  orderBy,
  addDoc,
  getDoc,
	getDocs,
  updateDoc,
  deleteDoc,
} from "firebase/firestore";

// Create
addDoc(collection(dbService, "폴더명(collection)"), 추가할객체); 
// collection안으로 객체( doc.data() ) 추가 이 때 doc.id는 자동으로 생성됨

// Read (단일 데이터 읽기)
const snapshot = await getDoc(doc(dbService, "폴더명(collection)", "파일명(doc.id)")); 
// 하나의 doc를 가져옴.
snapshot.data() // 가져온 doc의 객체 내용
snapshot.id // 가져온 doc의 id

// Read (내 Firestore collection 내에 변경이 생길 때 마다 실시간으로 읽기)
const q = query(
      collection(dbService, "폴더명(todos)"),
      orderBy("createdAt", "desc") // 해당 collection 내의 docs들을 createdAt 속성을 내림차순 기준으로 
    );

onSnapshot(q, (snapshot) => {  // q (쿼리)안에 담긴 collection 내의 변화가 생길 때 마다 매번 실행됨
	 snapshot.docs.map((doc) => {
      const newState = {
				id: doc.id,
				...doc.data() // doc.data() : { text, createdAt, ...  }
			}
    });
});

// Read (query에 해당하는 모든 docs 가져오기)
const querySnapshot = await getDocs(q);
  // doc.id는 DB가 자체적으로 생성하는 값으로, id도 함께 포함시키기 위해 객체 재구성
	const newArr = [];
  querySnapshot.forEach((doc) => {
    const newObj = {
      id: doc.id,
      ...doc.data(),
    };
		newArr.push(newObj);
  });

// Update
updateDoc(doc(dbService, "폴더명(collection)", "파일명(doc.id)"), { text: "변경할 값" }) 
// doc 지정 후 변경할 속성 및 값 지정

// Delete
deleteDoc(doc(dbService, "폴더명(collection)", "파일명(doc.id)")); // 해당 doc 를 삭제

 

이렇게 firebase를 사용하면 더 이상 AsyncStorage를 사용하지 않아도 된다.

AsyncStorage는 웹개발할 때 쓰던 local storage와 비슷한데, 이제는 firebase에 data를 저장할 수 있으니 필요 없어졌다.

 

위의 코드들을 투두리스트에 적용해보면 아래 코드와 같다.

// add Todo
  const addTodo = async () => {
    // setTodos((prev) => [...prev, newTodo]);

    // 바로 database에 변화를 주기만하면 onSnapshot이 인지를 해서 setTodos를 해주기 때문에
    // setTodos를 일일히 해줄 필요가 없어졌다.
    // addDoc은 collection만 지정하면 된다 (document id는 자동으로 랜덤생성)
    await addDoc(collection(dbService, "todos"), newTodo); // todos는 자동으로 생성되니 미리 만들 필요 X
    setText("");
  };

예시로 todo add 부분만 가져왔는데 delete/edit/done 부분도 마찬가지이다.

굳이 setTodos를 할 필요 없이 addDoc API를 사용하면 손쉽게 투두가 추가된다.

AsyncStorage를 사용할 때는 현재의 최신 todo를 저장해야 해서 useEffect()를 사용했는데 이제는 그러지 않아도 된다.

 

// useEffect(() => {
  //   // 현재의 최신 todos를 AsyncStorage에 저장
  //   const saveTodos = async () => {
  //     await AsyncStorage.setItem("todos", JSON.stringify(todos));
  //   };
  //   if (todos.length > 0) saveTodos();
  // }, [todos]);
  // 더이상 asyncstorage에 저장할 필요가 없다

  useEffect(() => {
    // const getData = async () => {
    //   const resp_todos = await AsyncStorage.getItem("todos"); // todos 배열
    //   //const resp_cat = await AsyncStorage.getItem("category"); // undefined / null

    //   setTodos(JSON.parse(resp_todos) ?? []);
    //   //setCategory(resp_cat ?? "js");
    // };
    // getData();

    // 1. onSnapshot API를 이용해서 todos collection에 변경이 생길 때마다
    // 2. todos collection 안의 모든 document들을 불러와서 setTodos한다
    const q = query(
      collection(dbService, "todos"),
      orderBy("createdAt", "desc")
    );

    // data 불러오기
    onSnapshot(q, (snapshot) => {
      const newTodos = snapshot.docs.map((doc) => {
        const newTodo = {
          id: doc.id,
          ...doc.data(), // doc.data() : { text, createdAt, ...  }
        };
        return newTodo;
      });
      setTodos(newTodos);
    });

    const getCategory = async () => {
      const snapshot = await getDoc(
        doc(dbService, "category", "currentCategory")
      );
      setCategory(snapshot.data().category);
    };
    getCategory();
  }, []);

 

이런 식으로 전에 쓰던 AsyncStorage 관련 코드를 주석처리하고 firebase에서 document들을 불러오는 형식으로

리팩토링하는 걸 배웠다. (사실 튜터님 강의를 보면서 따라해본거나 마찬가지...ㅋㅋㅋ)

 

firebase 프로젝트

여기서 이벤트(isDone, isEdit 등)이 발생할 때마다 false가 true로 바뀌기도 하고 수정하면 text 부분이 제대로 바뀌는 걸 확인할 수가 있다.

 

처음에 category를 설정할 때는 미리 컬렉션을 만들어두고 시작했는데 todos는 todo add를 할 때마다 새로운 문서가 추가되기 때문에 굳이 만들고 시작하지 않았다.

 

 

 

 

 

 

 


분명 firebase 연동을 배웠었는데 앱개발이라고 다르게 느껴지나보다...ㅋㅋ

그 때 프로젝트를 진행하면서 나름 괜찮게 진행했다고 생각했는데, 막상 다 끝나고 공부하지 않으니 새롭게 배우는 거와 마찬가지 같아서 좀 내 실력에 현타가 왔다 ㅋㅋㅋ

 

그래도 어쩌겠어...다시 해야지...

저번 프로젝트 할 때는 공식 문서를 가장 나중에 살펴봤던 것 같은데 이번에는 공식 문서도 읽어봤다.

https://firebase.google.com/docs/firestore/quickstart?hl=en&authuser=0 

 

Cloud Firestore 시작하기  |  Firebase

Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니

firebase.google.com

 

공식문서를 보니 새삼스레 떠오르는 지난 프로젝트의 코드들....ㅋㅋㅋㅋ

새로운 걸 배우는 것보다 예전에 배웠던 부분을 다시 짚어봐야 할 시점이 온 것같다.

 

여튼, React Native를 공부하면서 firebase를 연동하는 걸 처음 배워서 이것도 정리하면 좋겠다는 생각이 들어서 정리했다.

미래의 내가 프로젝트를 진행할 때 필요할 수도 있으니...ㅋㅋㅋ

728x90