React/Firebase
Firebase v9 + React 로 CRUD
또롱또
2022. 5. 28. 03:31
728x90
Firebase는 platform provided by google.
코드에 주석으로 뭐하는 코드인지 메모를 조금 해뒀다.
사진이 안보이면 클릭하면 커진다.
참고하면 좋은 자료들
1. https://travis.media/how-to-use-firebase-with-react/#20211130-getDoc
2. 파이어베이스 documents
3. https://www.youtube.com/watch?v=9zdvmgGsww0&list=PL4cUxeGkcC9jERUGvbudErNCeSZHWUVlb
1. 리액트 설치
yarn create react-app .
2. Firebase 추가
yarn add firebase
3. 아래로 이동해서 로그인까지한다.
https://console.firebase.google.com/u/0/
4. 프로젝트 추가 하면 플젝 이름정하고 하는데
뭐 건들지 말고 다 그냥 default 로 넘어가자.
5.톱니바퀴 -> 프로젝트 설정
6. 빨간동그라미 클릭해서 웹 추가 페이지로 간다
등록할때 호스팅 버튼은 누르지 말자. 궁금하면 구글링하는것도 좋겠다.
7. vscode에 firebase-config.js 생성 한후에,
아까 웹 추가하고 나온 페이지에서 아래 빨간부분 복붙.
8. 데이터 베이스를 만든다.
웹 추가 페이지에서 콘솔로이동 한 후, 아래 사진에 있는 1, 2번 버튼만 클릭하면된다.
프로덕션모드에서 시작, 클라우드위치(한국살면 asia하면된다) 를 고른다.
9. DB규칙을 바꾼다 -> read write가 초기값은 false인데 true로 수정하고 게시한다.
10. DB생성 화면에 있는 번호 순서대로 클릭하고 입력한다.
11. firebase-config.js에 꺼내쓴다는 변수 생성.
firebaseConfig는 각자꺼 쓰고 나머진 복붙.
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import {getFirestore} from "@firebase/firestore"
// 파이어스토어에 접근할수 있게해주는 ID 등등 - 로그인해야지 준다
const firebaseConfig = {
apiKey: "aas6nquiMi_BNRvbQ3pytdYVUNU",
authDomain: "fir-study-2c509.firebaseapp.com",
projectId: "fir-study-2c509",
storageBucket: "fir-study-2c509.appspot.com",
messagingSenderId: "31231445033",
appId: "1:307451445033:web:de010b795d33e57bff4138",
measurementId: "G-N2SH1342EJ7"
};
const app = initializeApp(firebaseConfig)
export const db = getFirestore(app);
12. db 연동되었나 체크하기 - App.js
import { useState, useEffect } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 접근해서 데이터를 꺼내게 도와줄 친구들
import { collection, getDocs } from "firebase/firestore";
function App() {
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 시작될때 한번만 실행
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
console.log(data);
}
getUsers();
},[])
return (
<div className="App">
</div>
);
}
export default App;
13. 콘솔창 확인 -> DB에서 데이터를 꺼내와야한다.
docs(....) 라고 되있으면 ....을 클릭하면 열린다.
14. CRUD의 R을 해줄 예정. 데이터를 한번 꺼내서 화면에 띄워보자
App.js
더보기
import { useState, useEffect, useId } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 접근해서 데이터를 꺼내게 도와줄 친구들
import { collection, getDocs } from "firebase/firestore";
function App() {
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 유니크 id를 만들기 위한 useId(); - react 18 기능으로, 이 훅을 이렇게 사용하는게 맞고 틀린지는 모른다.
const uniqueId = useId();
console.log(uniqueId)
// 시작될때 한번만 실행
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
// users에 data안의 자료 추가. 객체에 id 덮어씌우는거
setUsers(data.docs.map((doc)=>({ ...doc.data(), id: doc.id})))
}
getUsers();
},[])
// 띄워줄 데이터 key값에 고유ID를 넣어준다.
const showUsers = users.map((value)=> (<div key={uniqueId}>
<h1>Name: {value.name}</h1>
<h1>Age: {value.age}</h1>
</div>))
return (
<div className="App">
{showUsers}
</div>
);
}
export default App;
15. DB 구조를 잘 기억하자
만약 새로운 사람이 등록되면 어디에 추가되야하는가? 정답: 가운데 문서
16. CRUD중의 C를 해볼 예정 input과 button을 만들어보자,
- 일단 input과 button에 값이 잘 들어오는지 확인
App.js
더보기
import { useState, useEffect, useId } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 접근해서 데이터를 꺼내게 도와줄 친구들
import { collection, getDocs } from "firebase/firestore";
function App() {
// input으로 받을 새로운 사람의 이름과 나이
const [newName, setNewName] = useState("");
const [newAge, setNewAge] = useState(0);
console.log(newName, newAge);
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 유니크 id를 만들기 위한 useId(); - react 18 기능으로, 이 훅을 이렇게 사용하는게 맞고 틀린지는 모른다.
const uniqueId = useId();
//console.log(uniqueId)
// 시작될때 한번만 실행
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
// users에 data안의 자료 추가. 객체에 id 덮어씌우는거
setUsers(data.docs.map((doc)=>({ ...doc.data(), id: doc.id})))
}
getUsers();
},[])
const createUsers = () =>{
}
// 띄워줄 데이터 key값에 고유ID를 넣어준다.
const showUsers = users.map((value)=> (<div key={uniqueId}>
<h1>Name: {value.name}</h1>
<h1>Age: {value.age}</h1>
</div>))
return (
<div className="App">
{/* onchange를 이용해서, 변하는 값을 state로 저장한다. */}
<input type="text" placeholder='name...' onChange={(event)=> {setNewName(event.target.value)}}/>
<input type="number" placeholder='age...' onChange={(event)=> {setNewAge(event.target.value)}}/>
<button onClick={createUsers}>Create User</button>
{showUsers}
</div>
);
}
export default App;
17. addDoc을 이용해서 DB로 값 보내기
더보기
import { useState, useEffect, useId } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 데이터에 접근을 도와줄 친구들
import { collection, getDocs, addDoc } from "firebase/firestore";
function App() {
// input으로 받을 새로운 사람의 이름과 나이
const [newName, setNewName] = useState("");
const [newAge, setNewAge] = useState(0);
console.log(newName, newAge);
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 유니크 id를 만들기 위한 useId(); - react 18 기능으로, 이 훅을 이렇게 사용하는게 맞고 틀린지는 모른다.
const uniqueId = useId();
//console.log(uniqueId)
// 시작될때 한번만 실행
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
// users에 data안의 자료 추가. 객체에 id 덮어씌우는거
setUsers(data.docs.map((doc)=>({ ...doc.data(), id: doc.id})))
}
getUsers();
},[])
const createUsers = async () =>{
// addDoc을 이용해서 내가 원하는 collection에 내가 원하는 key로 값을 추가한다.
await addDoc(usersCollectionRef, {name: newName, age:newAge});
}
// 띄워줄 데이터 key값에 고유ID를 넣어준다.
const showUsers = users.map((value)=> (<div key={uniqueId}>
<h1>Name: {value.name}</h1>
<h1>Age: {value.age}</h1>
</div>))
return (
<div className="App">
{/* onchange를 이용해서, 변하는 값을 state로 저장한다. */}
<input type="text" placeholder='name...' onChange={(event)=> {setNewName(event.target.value)}}/>
<input type="number" placeholder='age...' onChange={(event)=> {setNewAge(event.target.value)}}/>
<button onClick={createUsers}>Create User</button>
{showUsers}
</div>
);
}
export default App;
18. CRUD의 U를 해볼 예정.
각 이름과 나이 정보아래에 버튼을 하나 주고, 버튼을 누르면 나이가 증가되게 해볼예정
처음에 생성할때 작성한 age가 문자열로 들어가있다.그래서 추가를 누를경우 아래 사진처럼 문자열뒤에 숫자가 붙는다.
그래서 createUsers() 만들때 Number()로 형변환을 해 주었다.
자세한건 소스코드를 보면 알수 있다.
더보기
import { useState, useEffect, useId } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 데이터에 접근을 도와줄 친구들
import { collection, getDocs, addDoc, updateDoc, doc } from "firebase/firestore";
function App() {
// input으로 받을 새로운 사람의 이름과 나이
const [newName, setNewName] = useState("");
const [newAge, setNewAge] = useState(0);
console.log(newName, newAge);
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 유니크 id를 만들기 위한 useId(); - react 18 기능으로, 이 훅을 이렇게 사용하는게 맞고 틀린지는 모른다.
const uniqueId = useId();
//console.log(uniqueId)
// 시작될때 한번만 실행 // 읽어오기 - R
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
// users에 data안의 자료 추가. 객체에 id 덮어씌우는거
setUsers(data.docs.map((doc)=>({ ...doc.data(), id: doc.id})))
}
getUsers();
},[])
// 생성 - C
const createUsers = async () =>{
// addDoc을 이용해서 내가 원하는 collection에 내가 원하는 key로 값을 추가한다.
await addDoc(usersCollectionRef, {name: newName, age:Number(newAge)});
}
// 업데이트 - U
const updateUser = async( id, age) =>{
// 내가 업데이트 하고자 하는 db의 컬렉션의 id를 뒤지면서 내가 수정하고자 하는 id랑 같은 id값을 가진 데이터를 찾는다
const userDoc = doc(db, "users", id)
// 내가 업데이트 하고자 하는 key를 어떻게 업데이트할지 준비,, 중요한점이 db에는 문자열로 저장되어있다. 그래서 createUsers()함수안에서 age를 생성할때 숫자열로 형변환 해줘야한다
const newField = {age: age + 1};
// updateDoc()을 이용해서 업데이트
await updateDoc(userDoc, newField);
}
// 띄워줄 데이터 key값에 고유ID를 넣어준다.
const showUsers = users.map((value)=> (<div key={uniqueId}>
<h1>Name: {value.name}</h1>
<h1>Age: {value.age}</h1>
{/* 증가버튼은 이 안에 있어야지, 각기 다른 데이터마다 붙는다, users data를 map으로 돌기때문에, 그 안의 id랑 age를 넣어주면 된다.*/}
{/* id를 넣어주는 이유는, 우리가 수정하고자 하는 데이터를 찾아야하기 때문에. */}
<button onClick={()=>{updateUser(value.id, value.age)}}>Increase Age</button>
</div>))
return (
<div className="App">
{/* onchange를 이용해서, 변하는 값을 state로 저장한다. */}
<input type="text" placeholder='name...' onChange={(event)=> {setNewName(event.target.value)}}/>
<input type="number" placeholder='age...' onChange={(event)=> {setNewAge(event.target.value)}}/>
<button onClick={createUsers}>Create User</button>
{showUsers}
</div>
);
}
export default App;
19. CRUD의 마지막 D를 해볼 예정.
업데이트랑 동일한 방법으로 id값 찾아서 지운다.
더보기
import { useState, useEffect, useId } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 데이터에 접근을 도와줄 친구들
import { collection, getDocs, addDoc, updateDoc, doc, deleteDoc } from "firebase/firestore";
import { async } from '@firebase/util';
function App() {
// input으로 받을 새로운 사람의 이름과 나이
const [newName, setNewName] = useState("");
const [newAge, setNewAge] = useState(0);
console.log(newName, newAge);
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 유니크 id를 만들기 위한 useId(); - react 18 기능으로, 이 훅을 이렇게 사용하는게 맞고 틀린지는 모른다.
const uniqueId = useId();
//console.log(uniqueId)
// 시작될때 한번만 실행 // 읽어오기 - R
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
// users에 data안의 자료 추가. 객체에 id 덮어씌우는거
setUsers(data.docs.map((doc)=>({ ...doc.data(), id: doc.id})))
}
getUsers();
},[])
// 생성 - C
const createUsers = async () =>{
// addDoc을 이용해서 내가 원하는 collection에 내가 원하는 key로 값을 추가한다.
await addDoc(usersCollectionRef, {name: newName, age:Number(newAge)});
}
// 업데이트 - U
const updateUser = async( id, age) =>{
// 내가 업데이트 하고자 하는 db의 컬렉션의 id를 뒤지면서 데이터를 찾는다
const userDoc = doc(db, "users", id)
// 내가 업데이트 하고자 하는 key를 어떻게 업데이트할지 준비,, 중요한점이 db에는 문자열로 저장되어있다. 그래서 createUsers()함수안에서 age를 생성할때 숫자열로 형변환 해줘야한다
const newField = {age: age + 1};
// updateDoc()을 이용해서 업데이트
await updateDoc(userDoc, newField);
}
// 삭제 - D
const deleteUser = async(id) =>{
// 내가 삭제하고자 하는 db의 컬렉션의 id를 뒤지면서 데이터를 찾는다
const userDoc = doc(db, "users", id);
// deleteDoc을 이용해서 삭제
await deleteDoc(userDoc);
}
// 띄워줄 데이터 key값에 고유ID를 넣어준다.
const showUsers = users.map((value)=> (<div key={uniqueId}>
<h1>Name: {value.name}</h1>
<h1>Age: {value.age}</h1>
{/* 증가버튼은 이 안에 있어야지, 각기 다른 데이터마다 붙는다, users data를 map으로 돌기때문에, 그 안의 id랑 age를 넣어주면 된다.*/}
{/* id를 넣어주는 이유는, 우리가 수정하고자 하는 데이터를 찾아야하기 때문에. */}
<button onClick={()=>{updateUser(value.id, value.age)}}>Increase Age</button>
<button onClick={()=>{deleteUser(value.id)}}>Delete User</button>
</div>))
return (
<div className="App">
{/* onchange를 이용해서, 변하는 값을 state로 저장한다. */}
<input type="text" placeholder='name...' onChange={(event)=> {setNewName(event.target.value)}}/>
<input type="number" placeholder='age...' onChange={(event)=> {setNewAge(event.target.value)}}/>
<button onClick={createUsers}>Create User</button>
{showUsers}
</div>
);
}
export default App;
20. CRUD때마다 화면을 다시 그리기
화면을 rerendering 하는 방법은 세가지만 기억하자, state, props, updateForce().
그중에 가장 만만한 state 로 해보겠다.
마지막 이 코드만 복붙하면 지금까지 한 내용이 다 들어있다.
주석확인만 잘 하면 될듯하다.
더보기
import { useState, useEffect, useId } from 'react';
import './App.css';
// 파이어베이서 파일에서 import 해온 db
import {db} from './firebase-config'
// db에 데이터에 접근을 도와줄 친구들
import { collection, getDocs, addDoc, updateDoc, doc, deleteDoc } from "firebase/firestore";
import { async } from '@firebase/util';
function App() {
// input으로 받을 새로운 사람의 이름과 나이
const [newName, setNewName] = useState("");
const [newAge, setNewAge] = useState(0);
// changed를 true로 바꿔주면 되지않을까?
const [changed, setChanged] = useState(false);
console.log(newName, newAge);
// 이따가 users 추가하고 삭제하는거 진행을 도와줄 state
const [users, setUsers] = useState([]);
// db의 users 컬렉션을 가져옴
const usersCollectionRef = collection(db, "users");
// 유니크 id를 만들기 위한 useId(); - react 18 기능으로, 이 훅을 이렇게 사용하는게 맞고 틀린지는 모른다.
const uniqueId = useId();
//console.log(uniqueId)
// 시작될때 한번만 실행 // 읽어오기 - R
useEffect(()=>{
// 비동기로 데이터 받을준비
const getUsers = async () => {
// getDocs로 컬렉션안에 데이터 가져오기
const data = await getDocs(usersCollectionRef);
// users에 data안의 자료 추가. 객체에 id 덮어씌우는거
setUsers(data.docs.map((doc)=>({ ...doc.data(), id: doc.id})))
}
getUsers();
// 뭐든 동작할때마다 changed가 true값으로 변경되니까 화면을 그리고 다시 false로 돌려줘야지 다시 써먹는다.
setChanged(false)
},[changed]) // 처음에 한번 그리고, changed가 불릴때마다 화면을 다시 그릴거다
// 생성 - C
const createUsers = async () =>{
// addDoc을 이용해서 내가 원하는 collection에 내가 원하는 key로 값을 추가한다.
await addDoc(usersCollectionRef, {name: newName, age:Number(newAge)});
// 화면 업데이트를 위한 state 변경
setChanged(true)
}
// 업데이트 - U
const updateUser = async( id, age) =>{
// 내가 업데이트 하고자 하는 db의 컬렉션의 id를 뒤지면서 데이터를 찾는다
const userDoc = doc(db, "users", id)
// 내가 업데이트 하고자 하는 key를 어떻게 업데이트할지 준비,, 중요한점이 db에는 문자열로 저장되어있다. 그래서 createUsers()함수안에서 age를 생성할때 숫자열로 형변환 해줘야한다
const newField = {age: age + 1};
// updateDoc()을 이용해서 업데이트
await updateDoc(userDoc, newField);
// 화면 업데이트를 위한 state 변경
setChanged(true)
}
// 삭제 - D
const deleteUser = async(id) =>{
// 내가 삭제하고자 하는 db의 컬렉션의 id를 뒤지면서 데이터를 찾는다
const userDoc = doc(db, "users", id);
// deleteDoc을 이용해서 삭제
await deleteDoc(userDoc);
// 화면 업데이트를 위한 state 변경
setChanged(true)
}
// 띄워줄 데이터 key값에 고유ID를 넣어준다.
const showUsers = users.map((value)=> (<div key={uniqueId}>
<h1>Name: {value.name}</h1>
<h1>Age: {value.age}</h1>
{/* 증가버튼은 이 안에 있어야지, 각기 다른 데이터마다 붙는다, users data를 map으로 돌기때문에, 그 안의 id랑 age를 넣어주면 된다.*/}
{/* id를 넣어주는 이유는, 우리가 수정하고자 하는 데이터를 찾아야하기 때문에. */}
<button onClick={()=>{updateUser(value.id, value.age)}}>Increase Age</button>
<button onClick={()=>{deleteUser(value.id)}}>Delete User</button>
</div>))
return (
<div className="App">
{/* onchange를 이용해서, 변하는 값을 state로 저장한다. */}
<input type="text" placeholder='name...' onChange={(event)=> {setNewName(event.target.value)}}/>
<input type="number" placeholder='age...' onChange={(event)=> {setNewAge(event.target.value)}}/>
<button onClick={createUsers}>Create User</button>
{showUsers}
</div>
);
}
export default App;
728x90