Just Do IT!
[React Native] react native 프로젝트와 firebase 연동하기 본문
firebase 연동하기
지난주에는 asyncstorage를 이용했었다면, 이번에는 firebase를 연동해서 투두리스트를 만드는 강의를 들었다.
처음에는 뭔가 오류가 계속 났는데 공식 문서도 보고 오타도(ㅎ) 고쳐보니 잘 연동되고 신기한 경험이었다.
나중에 프로젝트 때도 유용할 것 같아서 블로그에도 미리 남겨둔다.
firebase 설치하기
npm instsall firebase --save
터미널에 위 명령어 입력해서 react native 프로젝트에 firebase 패키지를 설치한다.
firebase.js 파일 만들기 (firebase 연동)
미리 firebase에서 프로젝트를 생성하고 프로젝트를 생성함에 따라 나오는 SDK 설정을 연동해야 한다.
// 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들을 불러오는 형식으로
리팩토링하는 걸 배웠다. (사실 튜터님 강의를 보면서 따라해본거나 마찬가지...ㅋㅋㅋ)
여기서 이벤트(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를 연동하는 걸 처음 배워서 이것도 정리하면 좋겠다는 생각이 들어서 정리했다.
미래의 내가 프로젝트를 진행할 때 필요할 수도 있으니...ㅋㅋㅋ
'개발 공부 > React Native' 카테고리의 다른 글
[React Native] ScrollView 대신 FlatList 사용하기 (0) | 2023.01.04 |
---|---|
[React Native] 영화 정보 API 사용하기 (TMDB) (0) | 2023.01.04 |
[React Native] react-navigation (0) | 2023.01.03 |
[React Native] AsyncStorage 사용법 (0) | 2022.12.30 |
[React Native] Expo 사용법 (0) | 2022.12.29 |