Как создать приложение с полным стеком с помощью Next.js 13 и Firebase

Next.js — это фреймворк React, значительно облегчающий создание мощных программ с полным стеком (интерфейс + бэк-энд).

Команда, разрабатывающая Next.js, недавно выпустила Next.js 13, который имеет много перспектив как новый app Компоненты каталога, сервера и клиента.

В этой статье вы узнаете, как использовать новый Next.js 13 и базу данных Firebase для создания приложения с полным стеком.

Прежде чем продолжить, эта статья предполагает, что у вас есть базовые знания о JavaScript, React и Next.js. Если вам нужно восстановить эти навыки, вот несколько начинающих ресурсов:

Теперь, если вы готовы, давайте погрузимся.

Как настроить проект Next.js 13

Чтобы настроить Next.js, необходимо установить Node.js и npm/yarn на компьютере. Если у вас нет, вы можете установить их с их официальных веб-сайтов: веб-сайт Node.js и веб-сайт npm (но npm включен при установке Node).

  1. В желаемом каталоге запустите терминал и выполните следующее
    npx create-next-app@latest --experimental-app.
  2. Введите название проекта, нажмите Enter и подождите, пока он установится.
  3. Будет создан новый каталог с названием проекта с необходимыми файлами.
  4. перейдите в новый каталог:
    cd my-project-name
  5. Чтобы запустить сервер разработки, выполните следующую команду:
    // if you're using yarn
    yarn run dev
    
    // if you're using npm
    npm run dev
    
  6. Выполнение этой команды запустит сервер разработки, и вы увидите, как работает программа Next.js 13
Снимок экрана-2023-02-15-at-5.33.52-PM
Программа Next.js 13

Как настроить Firebase в Next.js

Firebase — это платформа BaaS (Backend-as-a-Service), которая предоставляет облачные серверные услуги, такие как проверка подлинности, база данных в реальном времени, облачное хранилище, аналитика и т.д.

В этом руководстве мы будем использовать Firebase в качестве нашей базы данных. Чтобы создать приложение Firebase, выполните следующие действия.

  1. Перейдите и войдите в свой аккаунт Google.

  2. Нажмите на Добавить проект и дайте название своему проекту. Нажмите на >> Далее.

  3. На следующем экране вы можете выбрать, хотите ли вы включить аналитику для своего проекта.

  4. Нажмите на Создать проект.

  5. Далее вам нужно создать веб-приложение. На домашней странице проекта щелкните значок веб-сайта для создания веб-приложения:

    Снимок экрана-2023-02-15-at-5.40.33-PM

  6. Дайте название своей веб-приложению и нажмите Зарегистрировать приложение.

    Снимок экрана-2023-02-15-at-5.40.48-PM

  7. Скопируйте файл конфигурации, который нам понадобится позже. Нажмите кнопку «Далее», пока не закончите.

  8. Снова на главной странице вашего проекта выбрать продукт для добавления в вашу программу. Для этого учебника добавьте только Аутентификация и Cloud Firestore.

    Снимок экрана-2023-02-15-at-6.33.34-PM

  9. Для аутентификации выберите Способ входа добавить Электронная почта/пароль.

После того, как вы успешно настроили firebase, теперь мы можем использовать его как серверную часть для программы Next.js 13.

Чтобы использовать Firebase из Next.js, выполните следующие действия.

  1. Установите новый SDK Firebase в свой проект Next.js, выполнив такую ​​команду на своем терминале

    yarn add firebase
    
    // or if you are using npm
    npm install firebase
    
  2. Создать .env файл в корневом каталоге вашего проекта Next.js и добавьте файлы конфигурации Firebase (которые вы скопировали ранее). Это должно выглядеть так:

    NEXT_PUBLIC_FIREBASE_API_KEY=api-key
    NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=auth-domain
    NEXT_PUBLIC_FIREBASE_PROJECT_ID=project-id
    NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=storage-bucket
    NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=sender-id
    NEXT_PUBLIC_FIREBASE_APP_ID=app-id
    NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=analytic-id
    
  3. Далее, чтобы сделать вещи более чистоплотными, в вашем src создать папку с названием firebase и создайте файл config.js с таким кодом:

    // Import the functions you need from the SDKs you need
    import { initializeApp, getApps } from "firebase/app";
    
    const firebaseConfig = {
        apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
        authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
        projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
        storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
        messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
        appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
        measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
    };
    
    // Initialize Firebase
    let firebase_app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
    
    export default firebase_app;
    

Теперь вы готовы, теперь вы готовы использовать Firebase в качестве базы данных в своей программе Next.js 13.

Как настроить аутентификацию

Когда дело доходит до создания приложений с полным стеком, первое, что приходит на ум, это аутентификация. Нам нужен способ регистрации и входа пользователей, и мы можем сделать это с помощью Firebase.

В вашем src > firebase каталог, создайте новый каталог под названием авт. Мы добавим весь наш код, связанный с проверкой подлинности firebase, в этот каталог.

Теперь создайте a signup.js файл в src > firebase > auth каталог с таким кодом:

import firebase_app from "../config";
import { createUserWithEmailAndPassword, getAuth } from "firebase/auth";

const auth = getAuth(firebase_app);


export default async function signUp(email, password) {
    let result = null,
        error = null;
    try {
        result = await createUserWithEmailAndPassword(auth, email, password);
    } catch (e) {
        error = e;
    }

    return { result, error };
}

Теперь давайте разберем это немного. То, что мы делаем здесь, это экспорт signUp()функция, использующая Firebase createUserWithEmailAndPassword() способ регистрации новых пользователей Теперь мы можем этим воспользоваться signUp() функционировать где угодно в нашем приложении.

В этом же каталоге добавим наш signIn() функция. Создать signin.js файл с таким кодом:

import firebase_app from "../config";
import { signInWithEmailAndPassword, getAuth } from "firebase/auth";

const auth = getAuth(firebase_app);

export default async function signIn(email, password) {
    let result = null,
        error = null;
    try {
        result = await signInWithEmailAndPassword(auth, email, password);
    } catch (e) {
        error = e;
    }

    return { result, error };
}

Как создать страницы входа и регистрации в Next.js

В Next.js 13 вы создаете новые страницы в app каталог. Каждая страница является папкой из a page.js файл – вы можете узнать больше о создании страниц из документов Next.js.

Чтобы создать страницу регистрации, создайте новую регистрация > page.js файл в вашем дополнение и добавьте следующий код:

'use client'
import React from "react";
import signUp from "@/firebase/auth/signup";
import { useRouter } from 'next/navigation'

function Page() {
    const [email, setEmail] = React.useState('')
    const [password, setPassword] = React.useState('')
    const router = useRouter()

    const handleForm = async (event) => {
        event.preventDefault()

        const { result, error } = await signUp(email, password);

        if (error) {
            return console.log(error)
        }

        // else successful
        console.log(result)
        return router.push("/admin")
    }
    return (<div className="wrapper">
        <div className="form-wrapper">
            <h1 className="mt-60 mb-30">Sign up</h1>
            <form onSubmit={handleForm} className="form">
                <label htmlFor="email">
                    <p>Email</p>
                    <input onChange={(e) => setEmail(e.target.value)} required type="email" name="email" id="email" placeholder="example@mail.com" />
                </label>
                <label htmlFor="password">
                    <p>Password</p>
                    <input onChange={(e) => setPassword(e.target.value)} required type="password" name="password" id="password" placeholder="password" />
                </label>
                <button type="submit">Sign up</button>
            </form>
        </div>
    </div>);
}

export default Page;`

По умолчанию каждая страница, которую вы добавляете в app каталог является компонентом сервера, что означает, что мы не можем добавить интерактивность на стороне клиента, как добавление onSubmit() к элементу формы. Чтобы добавить эту интерактивность на стороне клиента, мы сообщаем Next.js, что нам необходим компонент Client, добавляя следующее в верхней части файла перед любым импортом:

'use client'

// component code

Таким же образом мы можем создать нашу страницу входа. Чтобы создать страницу входа, создайте новую вход > page.js файл в вашем дополнение и добавьте следующий код:

'use client'
import React from "react";
import signIn from "@/firebase/auth/signin";
import { useRouter } from 'next/navigation'

function Page() {
    const [email, setEmail] = React.useState('')
    const [password, setPassword] = React.useState('')
    const router = useRouter()

    const handleForm = async (event) => {
        event.preventDefault()

        const { result, error } = await signIn(email, password);

        if (error) {
            return console.log(error)
        }

        // else successful
        console.log(result)
        return router.push("/admin")
    }
    return (<div className="wrapper">
        <div className="form-wrapper">
            <h1 className="mt-60 mb-30">Sign up</h1>
            <form onSubmit={handleForm} className="form">
                <label htmlFor="email">
                    <p>Email</p>
                    <input onChange={(e) => setEmail(e.target.value)} required type="email" name="email" id="email" placeholder="example@mail.com" />
                </label>
                <label htmlFor="password">
                    <p>Password</p>
                    <input onChange={(e) => setPassword(e.target.value)} required type="password" name="password" id="password" placeholder="password" />
                </label>
                <button type="submit">Sign up</button>
            </form>
        </div>

    </div>);
}

export default Page;

Как прослушать изменения аутентификации

Во всей нашей программе мы хотим иметь возможность определить, вошел ли определенный пользователь или нет. Мы можем создавать защищенные страницы и отображать только определенное содержимое авторизованного пользователя. Firebase предоставляет нам onAuthStateChanged() метод, к которому мы можем прислушиваться к изменениям.

Чтобы сделать пользовательские данные из вышеупомянутого метода доступными в нашей программе, мы собираемся использовать React Context API. Создайте папку с названием контекст в вашем src каталог. Внутри контекст создать файл под названием AuthContext.js и добавьте следующий код:

import React from 'react';
import {
    onAuthStateChanged,
    getAuth,
} from 'firebase/auth';
import firebase_app from '@/firebase/config';

const auth = getAuth(firebase_app);

export const AuthContext = React.createContext({});

export const useAuthContext = () => React.useContext(AuthContext);

export const AuthContextProvider = ({
    children,
}) => {
    const [user, setUser] = React.useState(null);
    const [loading, setLoading] = React.useState(true);

    React.useEffect(() => {
        const unsubscribe = onAuthStateChanged(auth, (user) => {
            if (user) {
                setUser(user);
            } else {
                setUser(null);
            }
            setLoading(false);
        });

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

    return (
        <AuthContext.Provider value={{ user }}>
            {loading ? <div>Loading...</div> : children}
        </AuthContext.Provider>
    );
};

Выше мы просто создаем поставщика, который возвращает пользовательский объект, если пользователь вошел в систему. Если пользователь не вошел в систему, мы просто возвращаем null.

Чтобы иметь возможность использовать значение, переданное в <AuthContext.Provider> мы экспортируем useAuthContext из файла. С этим мы можем использовать user значение.

Прежде чем мы сможем использовать этот контекст, нам нужно обратить все наши компоненты AuthContextProvider. Откройте src > приложение > layout.js файл и отредактируйте код с помощью следующего:

'use client'
import './globals.css'
import { AuthContextProvider } from '@/context/AuthContext'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      {/*
        <head /> will contain the components returned by the nearest parent
        head.js. Find out more at 
      */}
      <head />
      <body>
        <AuthContextProvider>
          {children}
        </AuthContextProvider>
      </body>
    </html>
  )
}

Теперь мы можем создавать защищенные страницы и показывать определенное содержимое разным пользователям.

Как создать защищенные страницы

Создайте каталог admin > page.js в вашем app и добавьте следующий код:

'use client'
import React from "react";
import { useAuthContext } from "@/context/AuthContext";
import { useRouter } from "next/navigation";
function Page() {
    const { user } = useAuthContext()
    const router = useRouter()

    React.useEffect(() => {
        if (user == null) router.push("/")
    }, [user])

    return (<h1>Only logged in users can view this page</h1>);
}

export default Page;

Если user есть null мы просто перенаправляем пользователя на главную страницу. Если пользователь нет nullмы показываем им защищенную страницу.

Как общаться с нашей базой данных

Теперь, когда мы получили часть пути проверки подлинности, мы можем сосредоточиться на общении с нашей базой данных. Для нашей базы данных, которую мы будем использовать Firestore.

Снова, чтобы сделать вещи более опрятными, создайте новое firebase > firestore в этом каталоге мы добавим весь код, связанный с Firestore.

Как добавить документы в Firestore

Создайте файл под названием addData.js внутри костер и добавьте следующий код:

import firebase_app from "../config";
import { getFirestore, doc, setDoc } from "firebase/firestore";

const db = getFirestore(firebase_app)
export default async function addData(colllection, id, data) {
    let result = null;
    let error = null;

    try {
        result = await setDoc(doc(db, colllection, id), data, {
            merge: true,
        });
    } catch (e) {
        error = e;
    }

    return { result, error };
}

На этом этапе этот тип кода должен быть вам знаком. Мы экспортируем функцию, которая добавляет данные в нашу базу данных firestore.

Теперь мы можем использовать это addData() функция из любого компонента для добавления данных в нашу базу данных:

'use client'
import addData from "@/firebase/firestore/addData";

export default function Home() {

  const handleForm = async () => {
    const data = {
      name: 'John snow',
      house: 'Stark'
    }
    const { result, error } = await addData('users', 'user-id', data)

    if (error) {
      return console.log(error)
    }
  }
  
  return (
    ...
  )
}

Как получить документ с Firestore

Используя аналогичный подход, мы можем получить документ из нашей базы Firestore.

Создать getData.js файл в Firestore и добавьте следующий код:

import firebase_app from "../config";
import { getFirestore, doc, getDoc } from "firebase/firestore";

const db = getFirestore(firebase_app)
export default async function getDoument(collection, id) {
    let docRef = doc(db, collection, id);

    let result = null;
    let error = null;

    try {
        result = await getDoc(docRef);
    } catch (e) {
        error = e;
    }

    return { result, error };
}

Вы также можете использовать getData() в любом из выбранных компонентов.

Вывод

В этой статье мы узнали, как создать программу с полным стеком с помощью Firebase и Next.js 13, интегрировав аутентификацию и взаимодействуя с нашей базой данных.

Счастливого кодирования!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *