---
title: "Hướng dẫn clone instagram với React JS và Firebase phần 3."
description: "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 😁."
canonical: "https://200lab.io/blog/huong-dan-clone-instagram-voi-react-js-va-firebase-phan-3"
published: "2021-10-06T14:29:22Z"
updated: "2026-08-21T07:17:49Z"
authors: ["TỪ QUỐC HƯNG"]
tags: ["Javascript"]
reading_minutes: 8
access: "public"
---

Ở 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.

![Firestore database](https://assets.200lab.io/images/2024/12/05/img-i-01-2-d08e70ffae2d2474d589.webp)

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 - Setup database](https://assets.200lab.io/images/2024/12/05/img-i-02-1-28308a7ba5200644485a.webp)

Ở 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, c_**họn xong bạn nhấn **Next** để sang step 2.

![Step 2 - Setup database](https://assets.200lab.io/images/2024/12/05/img-i-03-1-505252b14cd7218a216c.webp)

Ở 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.

![](https://assets.200lab.io/images/2024/12/05/img-i-04-1-f8e395392d13d20fd06d.webp)

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.

![](https://assets.200lab.io/images/2024/12/05/img-07-post-item-exam-3-8bc80d1e892379b5f39a.webp)

Để 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.

![Step 1 - create collection](https://assets.200lab.io/images/2024/12/05/img-i-05-8ce018842227da588d70.webp)

Ở đâ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.

![Step 2 - create collection](https://assets.200lab.io/images/2024/12/05/img-i-06-ba887826a2686d842e74.webp)

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.

![post collection](https://assets.200lab.io/images/2024/12/05/img-i-07-e890a8298b1c20617f80.webp)

## 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 🤭.

![](https://assets.200lab.io/images/2024/12/05/img-i-08-8646696bf840046a6b1b.webp)

![](https://assets.200lab.io/images/2024/12/05/img-i-09-f6283398c55eb895b2f4.webp)

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.

![](https://assets.200lab.io/images/2024/12/05/img-i-10-1-c295e9103054b2b7ba7c.webp)

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.

![](https://assets.200lab.io/images/2024/12/05/img-i-11-78c74eb9a22bec294cba.webp)

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:

![](https://assets.200lab.io/images/2024/12/05/img-i-14-2c5a7666114e16b5f479.webp)

`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.

![](https://assets.200lab.io/images/2024/12/05/img-i-12-63b8886d0a0915d11d6a.webp)

![](https://assets.200lab.io/images/2024/12/05/img-i-13-a5e416defb75cae0c2a5.webp)

## 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 🤗

## Đọc thêm

- [Event Loop là gì? Cơ chế hoạt động của Event Loop trong JavaScript](https://200lab.io/blog/event-loop-la-gi.md): Event Loop là một cơ chế cho phép xử lý các tác vụ bất đồng bộ trong JavaScript, sử dụng một vòng lặp vô tận để kiểm tra, quản lý các tác vụ.
- [So sánh Golang và NodeJS chi tiết](https://200lab.io/blog/so-sanh-golang-vs-nodejs.md): Golang và NodeJS khác nhau như thế nào? Golang và Nodejs từ lâu đã trở thành chủ đề sôi nổi. Nodejs đã chiếm ưu thế trong một khoảng thời gian dài. Golang liệu có đủ sức thuyết phục để chuyển đổi?
- [ReactJS Tutorial for Beginners Phần 2](https://200lab.io/blog/reactjs-tutorial-for-beginners-phan-2.md): Trong bài viết này chúng ta sẽ đi qua năm nội dung đầu tiên của tutorial
- [ReactJS vs React Native - Gà cùng một mẹ liệu có giống nhau?](https://200lab.io/blog/reactjs-vs-react-native.md): Bạn có đang rối giữa ReactJS vs React Native? Nên chọn cái nào thì tốt hơn? Có thể tái sử dụng code của ReactJS cho React Native hay không? Hãy khám phá câu trả lời thông qua bài viết so sánh ReactJS vs React Native này bạn nhé!
- [Netflix Clone với ReactJS, Styled Components và Firebase (Firestore & Auth) - Phần 7](https://200lab.io/blog/netflix-clone-voi-reactjs-styled-components-va-firebase-firestore-auth-phan-7.md): Nối tiếp phần 6 của series, trong phần này, chúng ta sẽ bắt tay vào code Sign Up page,config lại phần router để đáp ứng được vấn đề Authentication kèm theo tạo custom hook để listening for Authentication. Không dài dòng nữa, Chúng ta bắt đầu thôi 😁.
- [Mọi bài viết chủ đề Javascript](https://200lab.io/blog/tags/javascript.md)

Toàn bộ nội dung: https://200lab.io/llms.txt
