Posting
Firebase에서 Firestore Database를 테스트 모드로 생성해준다
Firebase Cloud Firestore 문서🔽
Firestore Database는 NoSQL 형태로, collection(폴더)과 document(문서)로 구성된다
[src/fbase.js]
...
firebase.initializeApp(firebaseConfig);
export const firebaseInstance = firebase;
export const authService = firebase.auth();
export const dbService = firebase.firestore();
fbase.js에 firestore를 추가해준다
[src/routes/Home.js]
import React, { useState } from "react";
import { dbService } from "fbase";
const Home = () => {
const [post, setPost] = useState("");
const onSubmit = async (event) => {
event.preventDefault();
await dbService.collection("posts").add({
post,
createdAt: Date.now(),
});
setPost("");
};
const onChange = (event) => {
const {
target: { value },
} = event;
setPost(value);
};
return (
<div>
<form onSubmit={onSubmit}>
<input
value={post}
onChange={onChange}
type="text"
placeholder="What's on your mind?"
maxLength={120}
/>
<input type="submit" value="Post" />
</form>
</div>
);
};
export default Home;
기본적인 form으로 posts라는 collection에 post라는 document를 추가하도록 코드를 작성해준다
Getting the Posts
[src/routes/Home.js]
import React, { useState, useEffect } from "react";
import { dbService } from "fbase";
const Home = () => {
const [post, setPost] = useState("");
const [posts, setPosts] = useState([]);
const getPosts = async () => {
const dbPosts = await dbService.collection("posts").get();
dbPosts.forEach((document) => {
const postObject = {
...document.data(),
id: document.id, // map 함수를 위해 id를 임의로 추가
};
// 이전 값들 앞에 forEach로 들어오는 데이터 붙이기
setPosts((prev) => [postObject, ...prev]);
});
};
useEffect(() => {
getPosts();
}, []);
...
return (
...
<div>
{posts.map((post) => (
<div key={post.id}>
<h4>{post.post}</h4>
</div>
))}
</div>
...
useEffect로 Firestore Database collection 데이터를 배열로 받아와, map 함수로 UI에 뿌려주자
Realtime Posts
[src/components/App.js]
const [userObj, setUserObj] = useState(null);
useEffect(() => {
// 사용자 정보 변화 감지
authService.onAuthStateChanged((user) => {
if (user) {
setIsLoggedIn(true);
setUserObj(user);
} else {
setIsLoggedIn(false);
}
setInit(true);
});
}, []);
App.js에서 user 데이터를 state로 받고 Home.js까지 props로 전달
const [userObj, setUserObj] = useState(null);
useEffect(() => {
// 사용자 정보 변화 감지
authService.onAuthStateChanged((user) => {
user ? setUserObj(user) : setUserObj(null);
setInit(true);
});
}, []);
return (
<>
{init ? (
<AppRouter isLoggedIn={Boolean(userObj)} userObj={userObj} />
) : (
"Loading..."
)}
<footer>© {new Date().getFullYear()} Firebase</footer>
</>
);
}
isLoggedIn 데이터를 userObj 데이터를 활용해 리팩토링
[src/routes/Home.js]
import React, { useState, useEffect } from "react";
import { dbService } from "fbase";
const Home = (props) => {
const [post, setPost] = useState("");
const [posts, setPosts] = useState([]);
useEffect(() => {
dbService.collection("posts").onSnapshot((snapshot) => {
const postArray = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setPosts(postArray);
});
}, []);
const onSubmit = async (event) => {
event.preventDefault();
await dbService.collection("posts").add({
text: post,
createdAt: Date.now(),
creatorId: props.userObj.uid, // 작성한 유저 id
});
setPost("");
};
const onChange = (event) => {
const {
target: { value },
} = event;
setPost(value);
};
return (
<div>
<form onSubmit={onSubmit}>
<input
value={post}
onChange={onChange}
type="text"
placeholder="What's on your mind?"
maxLength={120}
/>
<input type="submit" value="Post" />
</form>
<div>
{posts.map((post) => (
<div key={post.id}>
<h4>{post.text}</h4>
</div>
))}
</div>
</div>
);
};
export default Home;
Home.js의 onSubmit 함수에 작성한 유저 id 정보를 추가할 수 있다!
데이터를 useEffect에서 snapshot으로 받아오는 방식으로 변경, 새로고침 없이 업데이트된다
Delete and Update
[src/components/Post.js]
import React from "react";
const Post = (props) => {
return (
<div>
<h4>{props.postObj.text}</h4>
{props.isOwner && (
<>
<button>Delete Post</button>
<button>Update Post</button>
</>
)}
</div>
);
};
export default Post;
[src/routes/Home.js]
...
<div>
{posts.map((post) => (
<Post
key={post.id}
postObj={post}
isOwner={post.creatorId === props.userObj.uid}
/>
))}
</div>
...
글을 Post 컴포넌트로 빼고, 작성자가 user 데이터와 일치한다면 수정/삭제 버튼이 보이도록 해준다
[src/components/Post.js]
import React, { useState } from "react";
import { dbService } from "fbase";
const Post = (props) => {
const [editing, setEditing] = useState(false);
const [newPost, setNewPost] = useState(props.postObj.text);
const onDeleteClick = async () => {
const ok = window.confirm("정말 삭제할까용?");
if (ok) {
await dbService.doc(`posts/${props.postObj.id}`).delete();
}
};
const toggleEditing = () => setEditing((prev) => !prev);
const onSubmit = async (event) => {
event.preventDefault();
await dbService.doc(`posts/${props.postObj.id}`).update({ text: newPost });
setEditing(false);
};
const onChange = (event) => {
const {
target: { value },
} = event;
setNewPost(value);
};
return (
<div>
{editing ? (
<>
<form onSubmit={onSubmit}>
<input
value={newPost}
onChange={onChange}
type="text"
placeholder="Edit your post"
required
/>
<input type="submit" value="Update" />
</form>
<button onClick={toggleEditing}>Cancel</button>
</>
) : (
<>
<h4>{props.postObj.text}</h4>
{props.isOwner && (
<>
<button onClick={onDeleteClick}>Delete Post</button>
<button onClick={toggleEditing}>Update Post</button>
</>
)}
</>
)}
</div>
);
};
export default Post;
firestore 함수로 글의 수정/삭제가 가능하도록 코드를 추가해준다
본 내용은 노마드코더의 '트위터 클론코딩'을 바탕으로 작성되었습니다.
'Back-end > Firebase' 카테고리의 다른 글
[노마드코더] #5 Edit Profile (0) | 2022.04.08 |
---|---|
[노마드코더] #4 File Upload (0) | 2022.04.06 |
[노마드코더] #2 Authentication (0) | 2022.03.18 |
[노마드코더] #1 Introduction (0) | 2022.03.11 |
[TIL] Firebase 기초 (2) | 2022.03.08 |