+2

Xây dựng ứng dụng full-stack với next.js và firebase: Hướng dẫn từng bước

Trong thế giới công nghệ phát triển nhanh chóng ngày nay, việc lựa chọn đúng bộ công cụ là điều cần thiết cho các doanh nhân và startup mong muốn nhanh chóng hiện thực hóa ý tưởng. Sự kết hợp giữa Next.js và Firebase cung cấp một giải pháp mạnh mẽ để nhanh chóng tạo mẫu và xây dựng ứng dụng. Điều này biến nó thành môi trường lý tưởng để thử nghiệm các ý tưởng mới với tốc độ quan trọng.

Với giao diện front-end linh hoạt, dựa trên thành phần của Next.js và các dịch vụ đám mây tất cả trong một của Firebase như xác thực, cơ sở dữ liệu và lưu trữ, bộ công cụ này giúp dễ dàng phát triển các dự án chứng minh khái niệm (PoC) và lặp lại các ý tưởng nhanh chóng mà không cần thiết lập cơ sở hạ tầng phức tạp.

Trong hướng dẫn này, chúng ta sẽ xây dựng một ứng dụng ghi chú đơn giản để chỉ ra bạn có thể chuyển từ ý tưởng sang ứng dụng hoạt động nhanh chóng như thế nào.

Ngoài ra, bạn có thể tìm hiểu: Firebase là gì? Các đặc điểm nổi bật của Firebase

Bạn sẽ xây dựng gì trong hướng dẫn này?

Chúng ta sẽ xây dựng một ứng dụng quản lý công việc đơn giản, nơi người dùng có thể:

  • Đăng ký và đăng nhập bằng Firebase Authentication.
  • Tạo và quản lý các công việc (các thao tác CRUD) được lưu trữ trong Firebase Firestore.
  • Ứng dụng sẽ được triển khai trên Vercel, sẵn sàng để đưa vào sản xuất.

Điều kiện tiên quyết

Dưới đây là danh sách nhanh về những thứ cần có trước khi tiếp tục:

  • Một tài khoản Firebase.
  • Kiến thức cơ bản về React và Next.js.
  • Node.js được cài đặt trên máy của bạn.

Bước 1: Thiết lập dự án Next.js

Mở terminal và gõ lệnh bên dưới:

npx create-next-app task-manager
cd task-manager

Lệnh này sẽ tạo một ứng dụng Next.js bên trong thư mục task-manager.

Cài đặt Firebase SDK

Cài đặt các gói Firebase cần thiết bằng lệnh bên dưới:

npm install firebase

Firebase SDK sẽ cho phép chúng ta tương tác với các dịch vụ bao gồm như Firestore và Authentication từ bên trong ứng dụng Next.js.

Bước 2: Thiết lập Firebase

Tạo dự án Firebase:

  • Truy cập Firebase console và tạo một dự án Firebase mới.
  • Kích hoạt Firebase Authentication và Firestore Database.

Định cấu hình Firebase Authentication

  • Trong phần Authentication, thêm phương thức đăng nhập mới bằng nhà cung cấp email/mật khẩu gốc. Trong phần Firestore Database, tạo cơ sở dữ liệu mới và bắt đầu ở chế độ thử nghiệm cho mục đích phát triển.

Tải xuống Firebase Config

  • Để kết nối ứng dụng của bạn với Firebase, bạn cần định cấu hình Firebase trong ứng dụng Next.js. Hãy truy cập Cài đặt Dự án trong Firebase Console, sau đó trong Ứng dụng của bạn, chọn Ứng dụng Web để lấy cấu hình Firebase. Sao chép cấu hình này vì bạn sẽ sử dụng nó để khởi tạo Firebase trong ứng dụng của bạn.

Bước 3: Khởi tạo Firebase trong ứng dụng Next.js

Tạo tệp cấu hình Firebase

  • Tạo một tệp có tên firebase.js bên trong thư mục src/ hoặc bất cứ nơi nào bạn muốn.
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import 'firebase/auth';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: 'YOUR_API_KEY',
  authDomain: 'YOUR_AUTH_DOMAIN',
  projectId: 'YOUR_PROJECT_ID',
  storageBucket: 'YOUR_STORAGE_BUCKET',
  messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
  appId: 'YOUR_APP_ID',
};

const app = initializeApp(firebaseConfig);

const db = getFirestore(app);
const auth = getAuth(app);

export { db, auth };

Thay thế các phần giữ chỗ bằng cấu hình Firebase bạn đã sao chép ở bước trước.

Bước 4: Xây dựng xác thực bằng Firebase

Trong bước này, chúng ta sẽ xây dựng phần xác thực nơi người dùng có thể đăng ký, đăng nhập và đăng xuất.

Trang đăng ký và đăng nhập

  • Tạo pages/signUp.js cho trang đăng ký:
import { useState } from 'react';
import { auth } from '../firebase';
import { useRouter } from 'next/router';
import { createUserWithEmailAndPassword } from 'firebase/auth';

const Signup = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState(null);
  const router = useRouter();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
        await createUserWithEmailAndPassword(auth, email, password);
        router.push('/tasks'); // Redirect to tasks page after signup
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div>
      <h2>Sign Up</h2>
      <form onSubmit={handleSubmit}>
        <input 
          type="email" 
          placeholder="Email" 
          value={email} 
          onChange={(e) => setEmail(e.target.value)} 
        />
        <input 
          type="password" 
          placeholder="Password" 
          value={password} 
          onChange={(e) => setPassword(e.target.value)} 
        />
        <button type="submit">Sign Up</button>
      </form>
      {error && <p>{error}</p>}
    </div>
  );
};

export default Signup;

Tạo pages/signIn.js cho trang đăng nhập:

import { useState } from 'react';
import { auth } from '../firebase';
import { useRouter } from 'next/router';
import { signInWithEmailAndPassword } from 'firebase/auth';

const Signin = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState(null);
  const router = useRouter();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
        await signInWithEmailAndPassword(auth, email, password);
        router.push('/tasks'); // Redirect to tasks page after login
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div>
      <h2>Sign In</h2>
      <form onSubmit={handleSubmit}>
        <input 
          type="email" 
          placeholder="Email" 
          value={email} 
          onChange={(e) => setEmail(e.target.value)} 
        />
        <input 
          type="password" 
          placeholder="Password" 
          value={password} 
          onChange={(e) => setPassword(e.target.value)} 
        />
        <button type="submit">Sign In</button>
      </form>
      {error && <p>{error}</p>}
    </div>
  );
};

export default Signin;

Bước 5: Quản lý công việc và các thao tác CRUD với Firestore

Bước này tập trung vào việc triển khai cốt lõi của ứng dụng: hệ thống quản lý công việc.

Trang công việc với các thao tác CRUD

  • Tạo pages/tasks.js nơi người dùng có thể thêm, xem và xóa công việc:
import { useState, useEffect } from 'react';
import { db, auth } from '../firebase';
import { useRouter } from 'next/router';
import { collection, query, where, onSnapshot, addDoc, deleteDoc, doc } from 'firebase/firestore';

const Tasks = () => {
  const [tasks, setTasks] = useState([]);
  const [task, setTask] = useState('');
  const [error, setError] = useState(null);
  const router = useRouter();

  useEffect(() => {
    if (!auth.currentUser) {
      router.push('/signin');
      return;
    }

    const q = query(
      collection(db, 'tasks'),
      where('userId', '==', auth.currentUser.uid)
    );

    const unsubscribe = onSnapshot(q, (snapshot) => {
      const newTasks = snapshot.docs.map((doc) => {
        return { id: doc.id, ...doc.data() };
      });
      setTasks(newTasks);
    });

    return () => unsubscribe();
  }, []);

  const handleAddTask = async (e) => {
    e.preventDefault();
    if (task.trim()) {
      try {
        await addDoc(collection(db, 'tasks'), {
          userId: auth.currentUser.uid,
          task,
          completed: false,
        });
        setTask('');
      } catch (err) {
        setError(err.message);
      }
    }
  };

  const handleDeleteTask = async (id) => {
    try {
      await deleteDoc(doc(db, 'tasks', id));
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div>
      <h2>Your Tasks</h2>
      <form onSubmit={handleAddTask}>
        <input
          type="text"
          value={task}
          onChange={(e) => setTask(e.target.value)}
          placeholder="Add a new task"
        />
        <button type="submit">Add Task</button>
      </form>
      {error && <p>{error}</p>}
      <ul>
        {tasks.map((task) => (
          <li key={task.id}>
            {task.task}
            <button onClick={() => handleDeleteTask(task.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Tasks;

Trang này cho phép người dùng:

  • Thêm công việc vào Firebase Firestore.
  • Xem các công việc được liên kết với người dùng của họ.
  • Xóa công việc khỏi Firestore.

Bước 6: Triển khai ứng dụng bằng Vercel

Để triển khai ứng dụng, bạn có thể sử dụng Vercel, được xây dựng dành riêng cho Next.js. Dưới đây là cách triển khai:

  • Đẩy mã của bạn lên kho lưu trữ GitHub.
  • Truy cập Vercel, đăng nhập bằng tài khoản GitHub của bạn và nhập kho lưu trữ.
  • Vercel tự động phát hiện đó là dự án Next.js và xử lý quá trình xây dựng và triển khai.

Kết luận

Bây giờ bạn đã xây dựng một ứng dụng full-stack bằng Next.js và Firebase, bao gồm các tính năng thiết yếu như xác thực và các thao tác CRUD với Firestore. Bộ công cụ này cung cấp một cách mạnh mẽ để xây dựng các ứng dụng không cần máy chủ, có thể mở rộng nhanh chóng, làm cho nó hoàn hảo cho cả MVP và ứng dụng sản xuất.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí