Ở phần 2 của series, mình đã hướng dẫn các bạn tạo phần header và bài post cho trang của chúng ta. Trong phần thứ 3 này, chúng ta sẽ cùng nhau giải quyết chuyện render cả một đống các bài post nhưng thế nào, cách implement Firebase Database, cách truy cập Database từ Firebase để lấy dữ liệu ra như thế nào. Chúng ta bắt đầu thôi 😁.
I. Cách triển khai firebase database
Đầu tiên, các bạn mở lại project bạn đã tạo ở trên firebase mà ở phần 1 mình có hướng dẫn, sau đó chọn phần Firestore Database ở phần thanh Navbar bên trái như hình.
Sau đó nhấn Create Database và nó sẽ hiện ra cái form cho chúng ta lựa chọn như hình.
Ở step 1 này firebase cho chúng ta 2 lựa chọn để setup rules cho database của chúng ta, Start in locked mode là set cho database của chúng ta là riêng tư chỉ ta mới có thể thao tác được với nó, còn Start in test mode thì đơn giản là bất kỳ ai cũng truy cập và thao tác được với database của chúng ta. Ở đây vì để học tập thôi nên mình chọn Start in test mode, chọn xong bạn nhấn Next để sang step 2.
Ở step 2 này firebase cho chúng ta chọn nơi cloud firestore data của chúng ta sẽ được lưu trữ. Mình để mặc định thôi và nhấn Enable để bắt đầu tạo. Sau khi tạo xong ta sẽ được như hình.
Cùng phân tích một tý về Instagram của chúng ta trước khi tạo database cho nó nè. Ta thấy mỗi bài post đều có một cấu trúc giống nhau gồm: Avatar + username, image, caption. Tạm thời những thứ còn lại chúng ta chưa cần quan tâm, chỉ cần tập trung vào những nội dung chính mà mọi bài post đều có thôi. Bạn có thể xem hình minh họa bên dưới.
Để tạo một một nơi lưu trữ cho các bài post của chúng ta thì ta nhấn vào start collection và nó sẽ hiện lên form cho ta điền thông tin như hình. Ở đây để lưu trữ nhiều bài post nên mình sẽ đặt là posts và nhấn Next để hoàn thành step 1 và sang step 2.
Ở đây firebase cũng gợi ý cho chúng ta luôn rồi đấy 😁.
Sang step 2 firebase cho chúng ta tạo các field, type của field đó và value của từng field luôn nè. Bài post của chúng ta sẽ gồm những field cơ bản như hình dưới.
Các bạn nhớ là sau khi điền các field và value cho nó nhấn Auto-ID nha để nó auto generate Id cho chúng ta nha 😁 không là nó không cho chúng ta Save đâu đó. Sau khi tạo xong ta được như hình.
II. Cấu hình firebase cho project
Trong thư mục src
của project ta tạo một file có tên firebaseConfig.js
để cấu hình cho firebase. Thật may mắn cho chúng ta là firebase cho chúng ta luôn đoạn code để chúng ta cấu hình ở trong project của mình.
Ta nhấn vào icon settting ở trên thanh Navbar bên trái và chọn project setting và kéo xuống cuối cùng, sau đó tick vào Config để lấy đoạn code config và quăng nó vào file firebaseConfig.js
mà ta vừa tạo. Nhớ là sau đó chúng ta phải export nó ra để mà có dùng đấy 🤭.
Trong project, chúng ta cài đặt firebase cho nó, để cài đặt bạn chỉ cần gõ lệnh npm i firebase --save
và enter để cài đặt.
file firebaseConfig.js
import {initializeApp} from 'firebase/app'
import { getAuth } from 'firebase/auth'
import { getFirestore } from 'firebase/firestore'
const firebaseApp = initializeApp( {
apiKey: "***************************************",
authDomain: "***************************************",
databaseURL: "***************************************",
projectId: "***************************************",
storageBucket: "***************************************",
messagingSenderId: "************",
appId: "***************************************",
measurementId: "************"
});
const db = getFirestore(firebaseApp);
const auth = getAuth(firebaseApp)
export { db, auth };
Các bạn có thể thấy ngoài đoạn code config ra thì mình có khai báo để sự dụng thêm 2 cái sevice mà firebase cung cấp cho chúng ta là firestrore nơi lưu trữ database, auth để xác thực thông tin (login, logout, create user, ...). Quá chi là tiện lợi phải không nào 😁.
III. Sử dụng useEffect để push hoặc pull data từ database
React cung cấp cho chúng ta 2 hook cơ bản là useState
và useEffect
để có thể quản lý state và quản lý vòng đời của một component.
Trong App.js
ta import 2 ông thần bên trên vào. Với useEffect
bạn có thể hiểu là nó là một function sẽ thực thi đoạn code bên trong nó theo một điều kiện cụ thể nào đó.
import React, { useState, useEffect } from "react";
import "./App.css";
import Header from "./components/Header/Header";
import PostItem from "./components/PostItem/PostItem";
function App() {
//useEffect -> Runs a piece of code based on a specific condition.
useEffect(() => {
// this is where the code runs
},[]);
return (
<div className="App">
{/* Header */}
<Header />
{/* Posts */}
<div className="Post__list">
<PostItem />
</div>
</div>
);
}
Nếu chúng ta để phần điều kiện []
trống như vầy thì khi component chứa nó load xong thì useEffect
chỉ chạy đúng một lần duy nhất, rất phù hợp để ta sử dụng nó cho việc tao tác với database để lấy data và render ra view.
Firebase cung cấp cho ta các phương thức để có thể lấy data từ database một cách dễ dàng (firebase nó thật sự là support tận răng cho chúng ta 😁). Trong App.js
ta import
thằng db
mà chúng ta đã khai báo ở file config lúc trước và import thêm phương thức collection()
và getDocs()
của firebase như sau:
import { db } from './firebaseConfig'
import { collection, getDocs } from 'firebase/firestore'
Trong App.js
ta tạo một function để get data như sau:
const getData = async () => {
const postsCol = collection(db, 'posts');
const snapshot = await getDocs(postsCol);
setPosts(
snapshot.docs.map(doc => ({
id: doc.id,
post: doc.data()
}))
)
}
Ta sử dụng collection()
để lấy data từ collection mà ta đã tạo lúc trước là posts. getDocs()
để lấy các docs kèm các thông tin khác có trong collection đó và trả về một biến có tên là snapshot
, ở đây là lấy data nên nó là một phương thức bất đồng bộ nên ta sử dụng asyn/await
để xử lý.
snapshot.docs
là nó đang tham chiếu đến cái list doc của collection đó, tức là các bài post trong collection posts của chúng ta.
Vì một collection posts có thể có nhiều bài post nên để lấy được hết tất cả data của các bài post ta phải sử dụng map()
để duyệt qua cái đống docs đó và add từng doc vào trong state của chúng ta.
Mỗi doc đều có id của mình nên mình lấy ra luôn để làm key cho từng post khi ta render ra một list các post. Sau khi code xong function để get data từ firebase ta quăng nó vào trong useEffect
là được.
Toàn bộ code trong App.js
import React, { useState, useEffect } from "react";
import "./App.css";
import Header from "./components/Header/Header";
import PostItem from "./components/PostItem/PostItem";
import { db } from './firebaseConfig'
import { collection, getDocs } from 'firebase/firestore'
function App() {
const [posts, setPosts] = useState([]);
//useEffect -> Runs a piece of code based on a specific condition.
useEffect(() => {
// this is where the code runs
getData();
},[]);
const getData = async () => {
const postsCol = collection(db, 'posts');
const snapshot = await getDocs(postsCol);
setPosts(
snapshot.docs.map(doc => ({
id: doc.id,
post: doc.data()
}))
)
}
return (
<div className="App">
{/* Header */}
<Header />
{/* Posts */}
<div className="Post__list">
{
posts.map(({id, post}) => (
<PostItem key={id} data={post}/>
))
}
</div>
</div>
);
}
export default App;
Mỗi khi render ra một item thì ta truyền data và key cho nó, attribute data`
bạn có thể đặt tên tùy ý cho nó nha, không nhất thiết là data
đâu 😁. Tuy nhiên mình chưa hứng data ở trong thằng component PostItem
nên nó vẫn là data tĩnh thôi. Ở firebase mình có tạo 2 bài post nên data render ra được hai bài post như hình.
Giờ chúng ta bắt đầu sử dụng data mà ta truyền vào như sau, trong component PostItem
ta code như sau:
props
là phần data ở component cha truyền vào cho component con, ta có thể đặt tên gì tùy thích nhé. const { data } = props;
là lấy data
mà ta đã gán vào attribute data
lúc ta truyền vào đó, truyền vào tên gì thì gọi ra tên đó đấy nha. Sau đó truyền data co từng nơi theo hình là được nè. Và ta có thành quả như hình.
IV. Tổng kết.
Trên đây là phần hướng dẫn của mình về cách render cả một đống các bài post nhưng thế nào, cách implement Firebase Database, cách truy cập Database để lấy dữ liệu ra phục vụ cho việc render các bài post của chúng ta. Cảm ơn các bạn đã đọc 🤗
TỪ QUỐC HƯNG
Đam mêm lập trình Frontend, Yêu thích việc setup workspace theo phong cách tối giản
follow me :
Bài viết liên quan
NodeJS là gì? Tại sao NodeJS lại phổ biến
Jul 09, 2024 • 8 min read
Event Loop là gì? Cơ chế hoạt động của Event Loop trong JavaScript
Jun 18, 2024 • 7 min read
So sánh Golang và NodeJS chi tiết
Oct 14, 2023 • 22 min read
Home Feed UI Instagram with TailwindCSS: Giới thiệu về series
Nov 28, 2022 • 2 min read
ReactJS Tutorial for Beginners Phần 2
Dec 12, 2021 • 3 min read
ReactJS vs React Native - Gà cùng một mẹ liệu có giống nhau?
Dec 12, 2021 • 14 min read