Firebase را با برنامه Next.js ادغام کنید

1. قبل از شروع

در این کد لبه، یاد خواهید گرفت که چگونه Firebase را با یک برنامه وب Next.js به نام Friendly Eats که یک وب سایت برای بررسی رستوران ها است، ادغام کنید.

برنامه وب Friendly Eats

برنامه وب تکمیل شده ویژگی های مفیدی را ارائه می دهد که نشان می دهد Firebase چگونه می تواند به شما در ساخت برنامه های Next.js کمک کند. این ویژگی ها شامل موارد زیر است:

  • ورود به سیستم با Google و عملکرد خروج از سیستم: برنامه وب تکمیل شده به شما امکان می دهد با Google وارد شوید و از سیستم خارج شوید. ورود و تداوم کاربر به طور کامل از طریق Firebase Authentication مدیریت می شود.
  • تصاویر: برنامه وب تکمیل شده به کاربرانی که وارد سیستم شده اند اجازه می دهد تصاویر رستوران را آپلود کنند. دارایی های تصویر در Cloud Storage برای Firebase ذخیره می شوند. Firebase JavaScript SDK یک URL عمومی برای تصاویر آپلود شده فراهم می کند. سپس این URL عمومی در سند رستوران مربوطه در Cloud Firestore ذخیره می‌شود.
  • نظرات: برنامه وب تکمیل‌شده به کاربرانی که وارد سیستم شده‌اند اجازه می‌دهد نظرات رستوران‌هایی را که شامل رتبه‌بندی ستاره و پیام متنی هستند، ارسال کنند. اطلاعات مرور در Cloud Firestore ذخیره می شود.
  • فیلترها: برنامه وب تکمیل‌شده به کاربرانی که وارد سیستم شده‌اند اجازه می‌دهد فهرست رستوران‌ها را بر اساس دسته، مکان و قیمت فیلتر کنند. همچنین می توانید روش مرتب سازی مورد استفاده را سفارشی کنید. داده ها از Cloud Firestore قابل دسترسی هستند و پرس و جوهای Firestore بر اساس فیلترهای استفاده شده اعمال می شوند.

پیش نیازها

  • آشنایی با Next.js و جاوا اسکریپت

چیزی که یاد خواهید گرفت

  • نحوه استفاده از Firebase با روتر برنامه Next.js و رندر سمت سرور.
  • نحوه ماندگاری تصاویر در Cloud Storage برای Firebase.
  • نحوه خواندن و نوشتن داده ها در پایگاه داده Cloud Firestore.
  • نحوه استفاده از ورود به سیستم با Google با Firebase JavaScript SDK.

آنچه شما نیاز دارید

  • Git
  • کیت توسعه جاوا
  • نسخه پایدار اخیر Node.js
  • مرورگر دلخواه شما، مانند گوگل کروم
  • یک محیط توسعه با ویرایشگر کد و ترمینال
  • یک حساب Google برای ایجاد و مدیریت پروژه Firebase شما
  • توانایی ارتقاء پروژه Firebase خود به طرح قیمت گذاری Blaze

2. محیط توسعه خود را تنظیم کنید

این لبه کد پایه کد شروع برنامه را فراهم می کند و به Firebase CLI متکی است.

مخزن را دانلود کنید

  1. در ترمینال خود، مخزن GitHub Codelab را شبیه سازی کنید:
    git clone https://github.com/firebase/friendlyeats-web.git
    
  2. مخزن GitHub شامل پروژه های نمونه برای چندین پلتفرم است. با این حال، این کد لبه فقط از دایرکتوری nextjs-start استفاده می کند. به دایرکتوری های زیر توجه کنید:
    • nextjs-start : حاوی کد شروعی است که بر اساس آن می سازید.
    • nextjs-end : حاوی کد راه حل برای برنامه وب تمام شده است.
  3. در ترمینال خود، به دایرکتوری nextjs-start بروید و وابستگی های لازم را نصب کنید:
    cd friendlyeats-web/nextjs-start
    npm install
    

Firebase CLI را نصب یا به‌روزرسانی کنید

دستور زیر را اجرا کنید تا بررسی کنید که Firebase CLI را نصب کرده اید و نسخه 12.5.4 یا بالاتر است:

firebase --version
  • اگر Firebase CLI را نصب کرده اید، اما نسخه 12.5.4 یا بالاتر نیست، آن را به روز کنید:
    npm update -g firebase-tools
    
  • اگر Firebase CLI را نصب نکرده‌اید، آن را نصب کنید:
    npm install -g firebase-tools
    

اگر به دلیل خطاهای مجوز نمی توانید Firebase CLI را نصب کنید، اسناد npm را ببینید یا از گزینه نصب دیگری استفاده کنید.

وارد Firebase شوید

  1. برای ورود به Firebase CLI دستور زیر را اجرا کنید:
    firebase login
    
  2. بسته به اینکه می خواهید Firebase داده ها را جمع آوری کند، Y یا N وارد کنید.
  3. در مرورگر خود، حساب Google خود را انتخاب کنید و سپس روی Allow کلیک کنید.

3. پروژه Firebase خود را راه اندازی کنید

در این بخش، یک پروژه Firebase را راه‌اندازی کرده و یک برنامه وب Firebase را با آن مرتبط می‌کنید. همچنین سرویس‌های Firebase را که توسط برنامه وب نمونه استفاده می‌شود، راه‌اندازی می‌کنید.

یک پروژه Firebase ایجاد کنید

  1. در کنسول Firebase ، روی ایجاد پروژه کلیک کنید.
  2. در کادر متنی نام پروژه خود را وارد کنید ، FriendlyEats Codelab (یا نام پروژه دلخواهتان) را وارد کنید و سپس روی Continue کلیک کنید.
  3. برای این کد لبه، شما نیازی به Google Analytics ندارید، بنابراین گزینه Enable Google Analytics for this project را غیرفعال کنید.
  4. روی ایجاد پروژه کلیک کنید.
  5. منتظر بمانید تا پروژه شما ارائه شود و سپس روی Continue کلیک کنید.
  6. در پروژه Firebase خود، به تنظیمات پروژه بروید. شناسه پروژه خود را یادداشت کنید زیرا بعداً به آن نیاز دارید. این شناسه منحصر به فرد نحوه شناسایی پروژه شما است (به عنوان مثال، در Firebase CLI).

یک برنامه وب به پروژه Firebase خود اضافه کنید

  1. در پروژه Firebase خود به نمای کلی پروژه خود بروید و سپس کلیک کنید e41f2efdd9539c31.png وب
  2. در کادر متنی نام مستعار برنامه ، یک نام مستعار برنامه به یاد ماندنی، مانند My Next.js app وارد کنید.
  3. کادر همچنین تنظیم Firebase Hosting برای این برنامه را انتخاب کنید.
  4. روی ثبت برنامه > بعدی > بعدی > ادامه به کنسول کلیک کنید.

طرح قیمت گذاری Firebase خود را ارتقا دهید

برای استفاده از چارچوب‌های وب، پروژه Firebase شما باید در طرح قیمت‌گذاری Blaze باشد، به این معنی که با یک حساب صورت‌حساب Cloud مرتبط است.

  • حساب Cloud Billing به یک روش پرداخت مانند کارت اعتباری نیاز دارد.
  • اگر تازه وارد Firebase و Google Cloud هستید، بررسی کنید که آیا واجد شرایط دریافت اعتبار 300 دلاری و یک حساب آزمایشی رایگان Cloud Billing هستید یا خیر.

با این حال، توجه داشته باشید که تکمیل این کد لبه نباید هزینه واقعی را متحمل شود.

برای ارتقای پروژه خود به پلن Blaze، مراحل زیر را دنبال کنید:

  1. در کنسول Firebase، برنامه خود را ارتقا دهید .
  2. در گفتگو، طرح Blaze را انتخاب کنید، و سپس دستورالعمل های روی صفحه را دنبال کنید تا پروژه خود را با یک حساب Cloud Billing مرتبط کنید.
    اگر نیاز به ایجاد یک حساب Cloud Billing دارید، ممکن است لازم باشد برای تکمیل ارتقا به جریان ارتقا در کنسول Firebase برگردید.

سرویس های Firebase را در کنسول Firebase تنظیم کنید

احراز هویت را تنظیم کنید

  1. در کنسول Firebase، به Authentication بروید.
  2. روی Get start کلیک کنید.
  3. در ستون ارائه دهندگان اضافی ، روی Google > فعال کردن کلیک کنید.
  4. در کادر متنی نام عمومی برای پروژه ، یک نام به یاد ماندنی مانند My Next.js app وارد کنید.
  5. از ایمیل کشویی پشتیبانی برای پروژه ، آدرس ایمیل خود را انتخاب کنید.
  6. روی ذخیره کلیک کنید.

Cloud Firestore را راه اندازی کنید

  1. در کنسول Firebase، به Firestore بروید.
  2. روی ایجاد پایگاه داده > شروع در حالت آزمایشی > بعدی کلیک کنید.
    بعداً در این کد، قوانین امنیتی را برای ایمن سازی داده های خود اضافه خواهید کرد. بدون افزودن قوانین امنیتی برای پایگاه داده خود، یک برنامه را به صورت عمومی توزیع یا افشا نکنید .
  3. از مکان پیش فرض استفاده کنید یا مکان مورد نظر خود را انتخاب کنید.
    برای یک برنامه واقعی، می خواهید مکانی را انتخاب کنید که به کاربران شما نزدیک باشد. توجه داشته باشید که این مکان را نمی‌توان بعداً تغییر داد، و همچنین به‌طور خودکار مکان سطل ذخیره‌سازی ابری پیش‌فرض شما خواهد بود (مرحله بعد).
  4. روی Done کلیک کنید.

Cloud Storage را برای Firebase تنظیم کنید

  1. در کنسول Firebase، به Storage بروید.
  2. روی شروع > شروع در حالت آزمایش > بعدی کلیک کنید.
    بعداً در این کد، قوانین امنیتی را برای ایمن سازی داده های خود اضافه خواهید کرد. بدون افزودن قوانین امنیتی برای سطل ذخیره‌سازی خود ، برنامه‌ای را به صورت عمومی توزیع یا افشا نکنید .
  3. محل سطل شما باید از قبل انتخاب شده باشد (به دلیل راه اندازی Firestore در مرحله قبل).
  4. روی Done کلیک کنید.

4. پایگاه کد استارتر را مرور کنید

در این بخش، چند قسمت از پایگاه کد شروع برنامه را بررسی می‌کنید که عملکردی را در این لبه کد به آن‌ها اضافه می‌کنید.

ساختار پوشه و فایل

جدول زیر شامل نمای کلی از پوشه و ساختار فایل برنامه است:

پوشه ها و فایل ها

شرح

src/components

برای فیلترها، سرصفحه‌ها، جزئیات رستوران و نظرات، اجزای سازنده واکنش نشان دهید

src/lib

توابع ابزاری که لزوماً به React یا Next.js مقید نیستند

src/lib/firebase

کد مخصوص Firebase و پیکربندی Firebase

public

دارایی های ثابت در برنامه وب، مانند نمادها

src/app

مسیریابی با روتر برنامه Next.js

src/app/restaurant

یک کنترل کننده مسیر API

package.json و package-lock.json

وابستگی های پروژه با npm

next.config.js

پیکربندی ویژه Next.js (عملکردهای سرور فعال هستند)

jsconfig.json

پیکربندی سرویس زبان جاوا اسکریپت

اجزای سرور و مشتری

این برنامه یک برنامه وب Next.js است که از App Router استفاده می کند. رندر سرور در سراسر برنامه استفاده می شود. به عنوان مثال، فایل src/app/page.js یک جزء سرور مسئول صفحه اصلی است. فایل src/components/RestaurantListings.jsx یک جزء سرویس گیرنده است که با دستور "use client" در ابتدای فایل مشخص شده است.

بیانیه های وارداتی

ممکن است متوجه عبارات وارداتی مانند زیر شوید:

import RatingPicker from "@/src/components/RatingPicker.jsx";

این برنامه از نماد @ استفاده می کند تا از مسیرهای وارداتی نسبی بی نظم جلوگیری کند و با نام مستعار مسیر امکان پذیر است.

API های مخصوص Firebase

تمام کدهای Firebase API در پوشه src/lib/firebase پیچیده شده است. سپس اجزای React فردی، توابع پیچیده شده را از دایرکتوری src/lib/firebase وارد می کنند، به جای اینکه توابع Firebase را مستقیما وارد کنند.

داده های ساختگی

اطلاعات تقلبی رستوران و بررسی در فایل src/lib/randomData.js موجود است. داده های آن فایل در کد موجود در فایل src/lib/fakeRestaurants.js جمع آوری می شود.

5. میزبانی محلی را با شبیه ساز Firebase Hosting راه اندازی کنید

در این بخش، از شبیه ساز میزبانی Firebase برای اجرای برنامه وب Next.js به صورت محلی استفاده خواهید کرد.

در پایان این بخش، شبیه ساز Firebase Hosting اپلیکیشن Next.js را برای شما اجرا می کند، بنابراین نیازی نیست Next.js را در یک فرآیند جداگانه برای شبیه سازها اجرا کنید.

یک حساب سرویس Firebase را دانلود و استفاده کنید

برنامه وب که در این کد لبه می‌سازید از رندر سمت سرور با Next.js استفاده می‌کند.

Firebase Admin SDK برای Node.js برای اطمینان از عملکرد قوانین امنیتی از کد سمت سرور استفاده می شود. برای استفاده از APIها در Firebase Admin، باید یک حساب سرویس Firebase را از کنسول Firebase دانلود و استفاده کنید.

  1. در کنسول Firebase، به صفحه حساب‌های سرویس در تنظیمات پروژه خود بروید.
  2. روی ایجاد کلید خصوصی جدید > ایجاد کلید کلیک کنید.
  3. پس از دانلود فایل در سیستم فایل شما، مسیر کامل آن فایل را دریافت کنید.
    به عنوان مثال، اگر فایل را در فهرست دانلودهای خود دانلود کرده باشید، مسیر کامل ممکن است به این صورت باشد: /Users/me/Downloads/my-project-id-firebase-adminsdk-123.json
  4. در ترمینال خود، متغیر محیطی GOOGLE_APPLICATION_CREDENTIALS را روی مسیر کلید خصوصی دانلود شده خود تنظیم کنید. در یک محیط یونیکس، دستور ممکن است به این صورت باشد:
    export GOOGLE_APPLICATION_CREDENTIALS="/Users/me/Downloads/my-project-id-firebase-adminsdk-123.json"
    
  5. این ترمینال را باز نگه دارید و از آن برای بقیه این کد لبه استفاده کنید، زیرا ممکن است متغیر محیطی شما در صورت شروع جلسه ترمینال جدید از بین برود.
    اگر جلسه ترمینال جدیدی را باز کنید، باید دستور قبلی را دوباره اجرا کنید.

پیکربندی Firebase خود را به کد برنامه وب خود اضافه کنید

  1. در کنسول Firebase، به تنظیمات پروژه خود بروید.
  2. در قسمت تنظیمات و پیکربندی SDK ، متغیر firebaseConfig را پیدا کنید و خواص و مقادیر آن را کپی کنید.
  3. فایل .env را در ویرایشگر کد خود باز کنید و مقادیر متغیر محیطی را با مقادیر پیکربندی کنسول Firebase پر کنید.
  4. در فایل، ویژگی های موجود را با مواردی که کپی کرده اید جایگزین کنید.
  5. فایل را ذخیره کنید.

برنامه وب را با پروژه Firebase خود راه اندازی کنید

برای اتصال برنامه وب به پروژه Firebase خود، این مراحل را دنبال کنید:

  1. در ترمینال خود، مطمئن شوید که چارچوب های وب در Firebase فعال هستند:
    firebase experiments:enable webframeworks
    
  2. Firebase را راه اندازی کنید:
    firebase init
    
  3. گزینه های زیر را انتخاب کنید:
    • Firestore: قوانین امنیتی را پیکربندی کرده و فایل ها را برای Firestore فهرست می کند
    • میزبانی: پیکربندی فایل ها برای میزبانی Firebase و (به صورت اختیاری) راه اندازی GitHub Action Deploys
    • Storage: یک فایل قوانین امنیتی را برای Cloud Storage پیکربندی کنید
    • شبیه سازها: شبیه سازهای محلی را برای محصولات Firebase راه اندازی کنید
  4. استفاده از پروژه موجود را انتخاب کنید و سپس شناسه پروژه را که قبلاً ذکر کرده اید وارد کنید.
  5. مقادیر پیش‌فرض را برای همه سؤال‌های بعدی انتخاب کنید تا به این سؤال برسید که در صورت وجود، در کدام منطقه می‌خواهید محتوای سمت سرور میزبانی کنید؟ . ترمینال پیامی را نشان می دهد که پایگاه کد Next.js موجود را در فهرست فعلی شناسایی می کند.
  6. برای این سوال که در صورت امکان در کدام منطقه می خواهید محتوای سمت سرور میزبانی کنید؟ ، مکانی را که قبلاً برای Firestore و Cloud Storage انتخاب کرده بودید انتخاب کنید.
  7. مقادیر پیش فرض را برای تمام سوالات بعدی انتخاب کنید تا به این سوال برسید که کدام شبیه سازهای Firebase را می خواهید راه اندازی کنید؟ . برای این سوال، Functions emulator و Hosting emulator را انتخاب کنید.
  8. مقادیر پیش فرض را برای سایر سؤالات انتخاب کنید.

استقرار قوانین امنیتی

این کد قبلاً دارای مجموعه‌ای از قوانین امنیتی برای Firestore و برای Cloud Storage برای Firebase است. پس از استقرار قوانین امنیتی، داده های پایگاه داده و سطل شما بهتر از سوء استفاده محافظت می شوند.

  1. برای استقرار این قوانین امنیتی، این دستور را در ترمینال خود اجرا کنید:
    firebase deploy --only firestore:rules,storage
    
  2. اگر از شما پرسیده شود: "Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?" ، بله را انتخاب کنید.

شبیه ساز Hosting را راه اندازی کنید

  1. در ترمینال خود، Hosting emulator را راه اندازی کنید:
    firebase emulators:start --only hosting
    
    ترمینال شما با پورتی پاسخ می دهد که در آن می توانید شبیه ساز Hosting را پیدا کنید، به عنوان مثال http://localhost:5000/ .

ترمینالی که نشان می دهد شبیه ساز میزبانی آماده است

  1. در مرورگر خود، با شبیه ساز Firebase Hosting به URL بروید.
  2. اگر این خطا را در صفحه وب مشاهده کردید که به این شکل شروع می شود: "Error: Firebase session cookie has incorrect..." ، باید تمام کوکی های خود را در محیط لوکال هاست خود حذف کنید. برای انجام این کار، دستورالعمل های موجود در حذف کوکی ها | اسناد DevTools .

یک خطای جلسه کوکی

حذف کوکی ها در DevTools

اکنون می توانید برنامه وب اولیه را ببینید! حتی اگر برنامه وب را روی یک URL لوکال هاست مشاهده می کنید، از سرویس های Firebase واقعی استفاده می کند که شما در کنسول خود پیکربندی کرده اید.

6. احراز هویت را به برنامه وب اضافه کنید

در این بخش، احراز هویت را به وب اپلیکیشن اضافه می کنید تا بتوانید وارد آن شوید.

عملکردهای ورود و خروج را پیاده سازی کنید

  1. در فایل src/lib/firebase/auth.js ، توابع onAuthStateChanged ، signInWithGoogle و signOut با کد زیر جایگزین کنید:
export function onAuthStateChanged(cb) {
        return _onAuthStateChanged(auth, cb);
}

export async function signInWithGoogle() {
        const provider = new GoogleAuthProvider();

        try {
                await signInWithPopup(auth, provider);
        } catch (error) {
                console.error("Error signing in with Google", error);
        }
}

export async function signOut() {
        try {
                return auth.signOut();
        } catch (error) {
                console.error("Error signing out with Google", error);
        }
}

این کد از API های Firebase زیر استفاده می کند:

Firebase API

شرح

GoogleAuthProvider

یک نمونه ارائه دهنده احراز هویت Google ایجاد می کند.

signInWithPopup

یک جریان احراز هویت مبتنی بر گفتگو را شروع می کند.

auth.signOut

کاربر را از سیستم خارج می کند.

در فایل src/components/Header.jsx ، کد از قبل توابع signInWithGoogle و signOut را فراخوانی می کند.

  1. در برنامه وب، صفحه را بازخوانی کنید و روی Sign in with Google کلیک کنید. برنامه وب به‌روزرسانی نمی‌شود، بنابراین مشخص نیست که آیا ورود به سیستم با موفقیت انجام شد یا خیر.

در تغییرات احراز هویت مشترک شوید

برای اشتراک در تغییرات احراز هویت، مراحل زیر را دنبال کنید:

  1. به فایل src/components/Header.jsx بروید.
  2. تابع useUserSession را با کد زیر جایگزین کنید:
function useUserSession(initialUser) {
        // The initialUser comes from the server through a server component
        const [user, setUser] = useState(initialUser);
        const router = useRouter();

        useEffect(() => {
                const unsubscribe = onAuthStateChanged(authUser => {
                        setUser(authUser);
                });
                return () => {
                        unsubscribe();
                };
        }, []);

        useEffect(() => {
                onAuthStateChanged(authUser => {
                        if (user === undefined) return;
                        if (user?.email !== authUser?.email) {
                                router.refresh();
                        }
                });
        }, [user]);

        return user;
}

وقتی تابع onAuthStateChanged مشخص می کند که تغییری در وضعیت احراز هویت وجود دارد، این کد از یک قلاب وضعیت React برای به روز رسانی کاربر استفاده می کند.

تغییرات را تأیید کنید

طرح‌بندی ریشه در فایل src/app/layout.js هدر را رندر می‌کند و در صورت موجود بودن، به‌عنوان پایه به کاربر منتقل می‌کند.

<Header initialUser={currentUser?.toJSON()} />

این بدان معناست که مؤلفه <Header> داده‌های کاربر را، در صورت وجود، در طول زمان اجرای سرور ارائه می‌کند. اگر در طول چرخه حیات صفحه پس از بارگیری اولیه صفحه، به‌روزرسانی‌هایی برای احراز هویت وجود داشته باشد، کنترل‌کننده onAuthStateChanged آنها را مدیریت می‌کند.

اکنون زمان آن است که برنامه وب را آزمایش کنید و آنچه را که ساخته اید تأیید کنید.

برای تأیید رفتار احراز هویت جدید، این مراحل را دنبال کنید:

  1. در مرورگر خود، برنامه وب را بازخوانی کنید. نام نمایشی شما در هدر ظاهر می شود.
  2. از سیستم خارج شوید و دوباره وارد شوید. صفحه در زمان واقعی و بدون رفرش صفحه به روز می شود. می توانید این مرحله را با کاربران مختلف تکرار کنید.
  3. اختیاری: روی برنامه وب کلیک راست کنید، View page source را انتخاب کنید و نام نمایشی را جستجو کنید. در منبع HTML خام که از سرور بازگردانده شده است ظاهر می شود.

7. مشاهده اطلاعات رستوران

برنامه وب شامل داده های ساختگی برای رستوران ها و نظرات است.

یک یا چند رستوران اضافه کنید

برای درج داده های رستوران ساختگی در پایگاه داده محلی Cloud Firestore خود، این مراحل را دنبال کنید:

  1. در برنامه وب، را انتخاب کنید 2cf67d488d8e6332.png > رستوران های نمونه را اضافه کنید .
  2. در کنسول Firebase در صفحه پایگاه داده Firestore ، رستوران ها را انتخاب کنید. اسناد سطح بالا را در مجموعه رستوران مشاهده می کنید که هر کدام نشان دهنده یک رستوران هستند.
  3. برای بررسی ویژگی‌های یک سند رستوران، روی چند سند کلیک کنید.

نمایش لیست رستوران ها

پایگاه داده Cloud Firestore شما اکنون رستوران هایی دارد که برنامه وب Next.js می تواند نمایش دهد.

برای تعریف کد واکشی داده، مراحل زیر را دنبال کنید:

  1. در فایل src/app/page.js ، مؤلفه سرور <Home /> را پیدا کنید و تماس تابع getRestaurants را بررسی کنید، که لیستی از رستوران ها را در زمان اجرای سرور بازیابی می کند. تابع getRestaurants را در مراحل زیر پیاده سازی می کنید.
  2. در فایل src/lib/firebase/firestore.js ، توابع applyQueryFilters و getRestaurants را با کد زیر جایگزین کنید:
function applyQueryFilters(q, { category, city, price, sort }) {
        if (category) {
                q = query(q, where("category", "==", category));
        }
        if (city) {
                q = query(q, where("city", "==", city));
        }
        if (price) {
                q = query(q, where("price", "==", price.length));
        }
        if (sort === "Rating" || !sort) {
                q = query(q, orderBy("avgRating", "desc"));
        } else if (sort === "Review") {
                q = query(q, orderBy("numRatings", "desc"));
        }
        return q;
}

export async function getRestaurants(filters = {}) {
        let q = query(collection(db, "restaurants"));

        q = applyQueryFilters(q, filters);
        const results = await getDocs(q);
        return results.docs.map(doc => {
                return {
                        id: doc.id,
                        ...doc.data(),
                        // Only plain objects can be passed to Client Components from Server Components
                        timestamp: doc.data().timestamp.toDate(),
                };
        });
}
  1. برنامه وب را بازخوانی کنید. تصاویر رستوران به صورت کاشی در صفحه ظاهر می شوند.

بررسی کنید که لیست رستوران ها در زمان اجرای سرور بارگیری می شوند

با استفاده از چارچوب Next.js، زمانی که داده ها در زمان اجرای سرور یا زمان اجرای سمت کلاینت بارگیری می شوند، ممکن است واضح نباشد.

برای تأیید بارگیری فهرست‌های رستوران در زمان اجرای سرور، این مراحل را دنبال کنید:

  1. در برنامه وب، DevTools را باز کنید و جاوا اسکریپت را غیرفعال کنید .

JavaScipt را در DevTools غیرفعال کنید

  1. برنامه وب را بازخوانی کنید. لیست رستوران ها هنوز بار می شود. اطلاعات رستوران در پاسخ سرور برگردانده می شود. وقتی جاوا اسکریپت فعال است، اطلاعات رستوران از طریق کد جاوا اسکریپت سمت سرویس گیرنده هیدراته می شود.
  2. در DevTools، جاوا اسکریپت را دوباره فعال کنید .

با شنوندگان عکس فوری Cloud Firestore به به‌روزرسانی‌های رستوران گوش دهید

در بخش قبل، نحوه بارگیری مجموعه اولیه رستوران ها از فایل src/app/page.js را مشاهده کردید. فایل src/app/page.js یک جزء سرور است و بر روی سرور ارائه می شود، از جمله کد واکشی داده Firebase.

فایل src/components/RestaurantListings.jsx یک جزء سرویس گیرنده است و می تواند برای هیدراته کردن نشانه گذاری ارائه شده توسط سرور پیکربندی شود.

برای پیکربندی فایل src/components/RestaurantListings.jsx برای هیدراته کردن نشانه‌گذاری ارائه‌شده توسط سرور، این مراحل را دنبال کنید:

  1. در فایل src/components/RestaurantListings.jsx کد زیر را که قبلا برای شما نوشته شده است رعایت کنید:
useEffect(() => {
        const unsubscribe = getRestaurantsSnapshot(data => {
                setRestaurants(data);
        }, filters);

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

این کد تابع getRestaurantsSnapshot() را فراخوانی می کند که شبیه تابع getRestaurants() است که در مرحله قبل پیاده سازی کردید. با این حال، این تابع عکس فوری یک مکانیسم پاسخ به تماس را فراهم می کند به طوری که هر بار که تغییری در مجموعه رستوران ایجاد می شود، پاسخ تماس فراخوانی می شود.

  1. در فایل src/lib/firebase/firestore.js ، تابع getRestaurantsSnapshot() را با کد زیر جایگزین کنید:
export function getRestaurantsSnapshot(cb, filters = {}) {
        if (typeof cb !== "function") {
                console.log("Error: The callback parameter is not a function");
                return;
        }

        let q = query(collection(db, "restaurants"));
        q = applyQueryFilters(q, filters);

        const unsubscribe = onSnapshot(q, querySnapshot => {
                const results = querySnapshot.docs.map(doc => {
                        return {
                                id: doc.id,
                                ...doc.data(),
                                // Only plain objects can be passed to Client Components from Server Components
                                timestamp: doc.data().timestamp.toDate(),
                        };
                });

                cb(results);
        });

        return unsubscribe;
}

تغییرات ایجاد شده از طریق صفحه پایگاه داده Firestore اکنون در برنامه وب در زمان واقعی منعکس می شود.

  1. در برنامه وب، را انتخاب کنید 27ca5d1e8ed8adfe.png > رستوران های نمونه را اضافه کنید . اگر عملکرد عکس فوری شما به درستی اجرا شود، رستوران‌ها در زمان واقعی و بدون بازخوانی صفحه ظاهر می‌شوند.

8. داده های کاربر را از برنامه وب ذخیره کنید

  1. در فایل src/lib/firebase/firestore.js ، تابع updateWithRating() را با کد زیر جایگزین کنید:
const updateWithRating = async (
        transaction,
        docRef,
        newRatingDocument,
        review
) => {
        const restaurant = await transaction.get(docRef);
        const data = restaurant.data();
        const newNumRatings = data?.numRatings ? data.numRatings + 1 : 1;
        const newSumRating = (data?.sumRating || 0) + Number(review.rating);
        const newAverage = newSumRating / newNumRatings;

        transaction.update(docRef, {
                numRatings: newNumRatings,
                sumRating: newSumRating,
                avgRating: newAverage,
        });

        transaction.set(newRatingDocument, {
                ...review,
                timestamp: Timestamp.fromDate(new Date()),
        });
};

این کد یک سند Firestore جدید را وارد می کند که نمایانگر بررسی جدید است. این کد همچنین سند Firestore موجود را به روز می کند که نشان دهنده رستوران با ارقام به روز شده برای تعداد رتبه بندی ها و میانگین امتیاز محاسبه شده است.

  1. تابع addReviewToRestaurant() را با کد زیر جایگزین کنید:
export async function addReviewToRestaurant(db, restaurantId, review) {
        if (!restaurantId) {
                throw new Error("No restaurant ID was provided.");
        }

        if (!review) {
                throw new Error("A valid review has not been provided.");
        }

        try {
                const docRef = doc(collection(db, "restaurants"), restaurantId);
                const newRatingDocument = doc(
                        collection(db, `restaurants/${restaurantId}/ratings`)
                );

                await runTransaction(db, transaction =>
                        updateWithRating(transaction, docRef, newRatingDocument, review)
                );
        } catch (error) {
                console.error(
                        "There was an error adding the rating to the restaurant.",
                        error
                );
                throw error;
        }
}

یک اکشن سرور Next.js را اجرا کنید

یک Next.js Server Action یک API مناسب برای دسترسی به داده‌های فرم، مانند data.get("text") برای دریافت مقدار متن از بار ارسال فرم ارائه می‌کند.

برای استفاده از Next.js Server Action برای پردازش ارسال فرم بررسی، مراحل زیر را دنبال کنید:

  1. در فایل src/components/ReviewDialog.jsx ، ویژگی action را در عنصر <form> پیدا کنید.
<form action={handleReviewFormSubmission}>

مقدار مشخصه action به تابعی اشاره دارد که در مرحله بعد پیاده سازی می کنید.

  1. در فایل src/app/actions.js ، تابع handleReviewFormSubmission() را با کد زیر جایگزین کنید:
// This is a next.js server action, which is an alpha feature, so
// use with caution.
// https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
export async function handleReviewFormSubmission(data) {
        const { app } = await getAuthenticatedAppForUser();
        const db = getFirestore(app);

        await addReviewToRestaurant(db, data.get("restaurantId"), {
                text: data.get("text"),
                rating: data.get("rating"),

                // This came from a hidden form field.
                userId: data.get("userId"),
        });
}

نظرات را برای یک رستوران اضافه کنید

شما از ارسال‌های نقد پشتیبانی کردید، بنابراین اکنون می‌توانید بررسی کنید که نظرات شما به درستی در Cloud Firestore درج شده است.

برای افزودن نظر و تأیید اینکه در Cloud Firestore درج شده است، این مراحل را دنبال کنید:

  1. در برنامه وب، یک رستوران را از صفحه اصلی انتخاب کنید.
  2. در صفحه رستوران کلیک کنید 3e19beef78bb0d0e.png .
  3. یک رتبه بندی ستاره انتخاب کنید.
  4. یک بررسی بنویسید.
  5. روی ارسال کلیک کنید. نظر شما در بالای لیست نظرات ظاهر می شود.
  6. در Cloud Firestore، در پنجره افزودن سند ، سند رستورانی را که بررسی کرده‌اید جستجو کنید و آن را انتخاب کنید.
  7. در صفحه مجموعه شروع ، رتبه بندی ها را انتخاب کنید.
  8. در صفحه افزودن سند ، سندی را برای بررسی خود پیدا کنید تا تأیید کنید که مطابق انتظار درج شده است.

اسناد در شبیه ساز Firestore

9. فایل های آپلود شده توسط کاربر را از برنامه وب ذخیره کنید

در این بخش، عملکردی را اضافه می‌کنید تا بتوانید هنگام ورود به سیستم، تصویر مرتبط با یک رستوران را جایگزین کنید. تصویر را در Firebase Storage آپلود می‌کنید و URL تصویر را در سند Cloud Firestore که نشان‌دهنده رستوران است، به‌روزرسانی می‌کنید.

برای ذخیره فایل‌های آپلود شده توسط کاربر از برنامه وب، این مراحل را دنبال کنید:

  1. در فایل src/components/Restaurant.jsx ، کدی را که هنگام آپلود فایل توسط کاربر اجرا می‌شود، مشاهده کنید:
async function handleRestaurantImage(target) {
        const image = target.files ? target.files[0] : null;
        if (!image) {
                return;
        }

        const imageURL = await updateRestaurantImage(id, image);
        setRestaurant({ ...restaurant, photo: imageURL });
}

هیچ تغییری لازم نیست، اما شما رفتار تابع updateRestaurantImage() را در مراحل زیر پیاده سازی می کنید.

  1. در فایل src/lib/firebase/storage.js ، توابع updateRestaurantImage() و uploadImage() را با کد زیر جایگزین کنید:
export async function updateRestaurantImage(restaurantId, image) {
        try {
                if (!restaurantId)
                        throw new Error("No restaurant ID has been provided.");

                if (!image || !image.name)
                        throw new Error("A valid image has not been provided.");

                const publicImageUrl = await uploadImage(restaurantId, image);
                await updateRestaurantImageReference(restaurantId, publicImageUrl);

                return publicImageUrl;
        } catch (error) {
                console.error("Error processing request:", error);
        }
}

async function uploadImage(restaurantId, image) {
        const filePath = `images/${restaurantId}/${image.name}`;
        const newImageRef = ref(storage, filePath);
        await uploadBytesResumable(newImageRef, image);

        return await getDownloadURL(newImageRef);
}

تابع updateRestaurantImageReference() قبلاً برای شما پیاده سازی شده است. این تابع یک سند رستوران موجود در Cloud Firestore را با URL تصویر به روز شده به روز می کند.

عملکرد آپلود تصویر را تأیید کنید

برای تأیید اینکه تصویر طبق انتظار آپلود می شود، این مراحل را دنبال کنید:

  1. در برنامه وب، تأیید کنید که وارد سیستم شده اید و یک رستوران را انتخاب کنید.
  2. کلیک 7067eb41fea41ff0.png و یک تصویر از فایل سیستم خود آپلود کنید. تصویر شما از محیط محلی شما خارج می شود و در فضای ذخیره سازی ابری آپلود می شود. تصویر بلافاصله پس از آپلود ظاهر می شود.
  3. برای Firebase به Cloud Storage بروید.
  4. به پوشه ای که نشان دهنده رستوران است بروید. تصویری که آپلود کردید در پوشه وجود دارد.

6cf3f9e2303c931c.png

10. نتیجه گیری

تبریک می گویم! یاد گرفتید که چگونه از Firebase برای افزودن ویژگی‌ها و عملکرد به برنامه Next.js استفاده کنید. به طور خاص از موارد زیر استفاده کردید:

بیشتر بدانید