שלב את Firebase עם אפליקציית Next.js

1. לפני שמתחילים

במעבדת קוד זה תלמדו כיצד לשלב את Firebase עם אפליקציית אינטרנט של Next.js בשם Friendly Eats, שהיא אתר לביקורות מסעדות.

אפליקציית האינטרנט של Friendly Eats

אפליקציית האינטרנט שהושלמה מציעה תכונות שימושיות המדגימות כיצד Firebase יכול לעזור לך לבנות אפליקציות Next.js. תכונות אלה כוללות את הדברים הבאים:

  • כניסה עם Google ופונקציונליות יציאה: אפליקציית האינטרנט שהושלמה מאפשרת לך להיכנס עם Google ולצאת. התחברות וההתמדה של המשתמש מנוהלות לחלוטין באמצעות אימות Firebase .
  • תמונות: אפליקציית האינטרנט שהושלמה מאפשרת למשתמשים שנכנסו להעלות תמונות של מסעדות. נכסי תמונה מאוחסנים ב- Cloud Storage for Firebase . Firebase JavaScript SDK מספק כתובת אתר ציבורית לתמונות שהועלו. כתובת האתר הציבורית הזו מאוחסנת לאחר מכן במסמך המסעדה הרלוונטי ב- Cloud Firestore .
  • ביקורות: אפליקציית האינטרנט שהושלמה מאפשרת למשתמשים שנכנסו לחשבון לפרסם ביקורות על מסעדות המורכבות מדירוג כוכבים והודעה מבוססת טקסט. מידע סקירה מאוחסן ב-Cloud Firestore.
  • מסננים: אפליקציית האינטרנט שהושלמה מאפשרת למשתמשים שנכנסו לסנן את רשימת המסעדות על סמך קטגוריה, מיקום ומחיר. ניתן גם להתאים אישית את שיטת המיון שבה נעשה שימוש. הגישה לנתונים מתבצעת מ-Cloud Firestore, ושאילתות Firestore מוחלות על סמך המסננים שבהם נעשה שימוש.

דרישות מוקדמות

  • ידע ב-Next.js וב-JavaScript

מה תלמד

  • כיצד להשתמש ב-Firebase עם נתב האפליקציה Next.js ועיבוד בצד השרת.
  • כיצד להתמיד בתמונות ב-Cloud Storage for Firebase.
  • כיצד לקרוא ולכתוב נתונים במסד נתונים של Cloud Firestore.
  • כיצד להשתמש בכניסה עם Google עם Firebase JavaScript SDK.

מה אתה צריך

  • Git
  • ערכת הפיתוח של Java
  • גרסה יציבה עדכנית של Node.js
  • דפדפן לבחירתך, כגון Google Chrome
  • סביבת פיתוח עם עורך קוד ומסוף
  • חשבון 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 שלך ​​ולאחר מכן לחץ על אפשר .

3. הגדר את פרויקט Firebase שלך

בחלק זה, תגדיר פרויקט Firebase ותשייך אליו אפליקציית אינטרנט של Firebase. כמו כן, תגדיר את שירותי Firebase המשמשים את אפליקציית האינטרנט לדוגמה.

צור פרויקט Firebase

  1. במסוף Firebase , לחץ על צור פרויקט .
  2. בתיבת הטקסט הזן את שם הפרויקט שלך , הזן את FriendlyEats Codelab (או שם פרויקט לבחירתך), ולאחר מכן לחץ על המשך .
  3. עבור מעבדת קוד זה, אינך זקוק ל-Google Analytics, אז כבה את האפשרות הפעל את Google Analytics עבור פרויקט זה .
  4. לחץ על צור פרויקט .
  5. המתן להקצאת הפרוייקט שלך ולאחר מכן לחץ על המשך .
  6. בפרויקט Firebase שלך, עבור אל הגדרות פרויקט . שים לב לזהות הפרויקט שלך כי אתה צריך אותו מאוחר יותר. מזהה ייחודי זה הוא האופן שבו הפרויקט שלך מזוהה (לדוגמה, ב-CLI של Firebase).

הוסף אפליקציית אינטרנט לפרויקט Firebase שלך

  1. נווט אל סקירת הפרויקט שלך בפרויקט Firebase שלך ​​ולאחר מכן לחץ e41f2efdd9539c31.png אינטרנט .
  2. בתיבת הטקסט של כינוי אפליקציה , הזן כינוי אפליקציה בלתי נשכח, כגון My Next.js app .
  3. בחר בתיבת הסימון הגדר גם אירוח Firebase עבור אפליקציה זו .
  4. לחץ על הרשמה אפליקציה > הבא > הבא > המשך למסוף .

שדרג את תוכנית התמחור שלך ב-Firebase

כדי להשתמש במסגרות אינטרנט, פרויקט Firebase שלך ​​צריך להיות בתוכנית התמחור של Blaze , מה שאומר שהוא משויך לחשבון Cloud Billing .

עם זאת, שים לב שהשלמת Codelab זה לא אמורה לגרור חיובים בפועל.

כדי לשדרג את הפרויקט שלך לתוכנית Blaze, בצע את השלבים הבאים:

  1. במסוף Firebase, בחר לשדרג את התוכנית שלך .
  2. בתיבת הדו-שיח, בחר את תוכנית Blaze ולאחר מכן עקוב אחר ההוראות שעל המסך כדי לשייך את הפרויקט שלך לחשבון Cloud Billing.
    אם היית צריך ליצור חשבון Cloud Billing, ייתכן שיהיה עליך לנווט חזרה לזרימת השדרוג במסוף Firebase כדי להשלים את השדרוג.

הגדר שירותי Firebase במסוף Firebase

הגדר אימות

  1. במסוף Firebase, נווט אל אימות .
  2. לחץ על התחל .
  3. בעמודה ספקים נוספים , לחץ על Google > הפעל .
  4. בתיבת הטקסט שם פונה לציבור עבור פרויקט , הזן שם בלתי נשכח, כגון My Next.js app .
  5. מהתפריט הנפתח דוא"ל תמיכה לפרויקט , בחר את כתובת הדוא"ל שלך.
  6. לחץ על שמור .

הגדר את Cloud Firestore

  1. במסוף Firebase, נווט אל Firestore .
  2. לחץ על צור מסד נתונים > התחל במצב בדיקה > הבא .
    בהמשך מעבדת הקוד הזה, תוסיף כללי אבטחה כדי לאבטח את הנתונים שלך. אין להפיץ או לחשוף אפליקציה בפומבי מבלי להוסיף כללי אבטחה עבור מסד הנתונים שלך .
  3. השתמש במיקום ברירת המחדל או בחר מיקום לבחירתך.
    עבור אפליקציה אמיתית, אתה רוצה לבחור מיקום שקרוב למשתמשים שלך. שימו לב שלא ניתן לשנות את המיקום הזה מאוחר יותר, והוא גם יהיה אוטומטית המיקום של דלי ברירת המחדל של Cloud Storage (השלב ​​הבא).
  4. לחץ על סיום .

הגדר אחסון בענן עבור Firebase

  1. במסוף Firebase, נווט אל אחסון .
  2. לחץ על התחל > התחל במצב בדיקה > הבא .
    בהמשך מעבדת הקוד הזה, תוסיף כללי אבטחה כדי לאבטח את הנתונים שלך. אין להפיץ או לחשוף אפליקציה בפומבי מבלי להוסיף כללי אבטחה עבור דלי האחסון שלך.
  3. המיקום של הדלי שלך כבר אמור להיות נבחר (עקב הגדרת Firestore בשלב הקודם).
  4. לחץ על סיום .

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

תצורת שירות שפת JavaScript

רכיבי שרת ולקוח

האפליקציה היא אפליקציית אינטרנט של Next.js שמשתמשת בנתב האפליקציות . עיבוד שרת משמש בכל האפליקציה. לדוגמה, הקובץ src/app/page.js הוא רכיב שרת האחראי על העמוד הראשי. הקובץ src/components/RestaurantListings.jsx הוא רכיב לקוח המסומן בהנחיית "use client" בתחילת הקובץ.

ייבוא ​​הצהרות

ייתכן שתבחין בהצהרות ייבוא ​​כמו הבאות:

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

האפליקציה משתמשת בסמל @ כדי להימנע מנתיבי ייבוא ​​יחסי מגושם ומתאפשרת על ידי כינויים של נתיבים .

ממשקי API ספציפיים ל-Firebase

כל קוד ה-API של Firebase עטוף בספריית src/lib/firebase . לאחר מכן ייבא רכיבי React בודדים את הפונקציות העטיפות מספריית src/lib/firebase , במקום לייבא ישירות פונקציות של Firebase.

נתונים מדומים

נתוני מסעדות וביקורות מדומים כלולים בקובץ src/lib/randomData.js . נתונים מאותו קובץ מורכבים בקוד בקובץ src/lib/fakeRestaurants.js .

5. הגדר אירוח מקומי באמצעות אמולטור Firebase Hosting

בסעיף זה, תשתמש באמולטור Firebase Hosting כדי להפעיל את אפליקציית האינטרנט Next.js באופן מקומי.

בסוף סעיף זה, אמולטור Firebase Hosting מריץ עבורך את אפליקציית Next.js, כך שלא תצטרך להפעיל את Next.js בתהליך נפרד לאמולטורים.

הורד והשתמש בחשבון שירות Firebase

אפליקציית האינטרנט שתבנה במעבדת קוד זה משתמשת בעיבוד בצד השרת עם Next.js .

ה- SDK של Firebase Admin עבור 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 Hosting ו(אופציונלי) הגדר פריסת GitHub Action
    • אחסון: הגדר קובץ כללי אבטחה עבור Cloud Storage
    • אמולטורים: הגדר אמולטורים מקומיים עבור מוצרי Firebase
  4. בחר השתמש בפרויקט קיים ולאחר מכן הזן את מזהה הפרויקט שציינת בעבר.
  5. בחר את ערכי ברירת המחדל עבור כל השאלות הבאות עד שתגיע לשאלה באיזה אזור תרצה לארח תוכן בצד השרת, אם רלוונטי? . המסוף מציג הודעה שהוא מזהה בסיס קוד Next.js קיים בספרייה הנוכחית.
  6. לשאלה באיזה אזור תרצה לארח תוכן בצד השרת, אם ישים? , בחר את המיקום שבחרת בעבר עבור Firestore ו-Cloud Storage.
  7. בחר את ערכי ברירת המחדל עבור כל השאלות הבאות עד שתגיע לשאלה אילו אמולטורים של Firebase אתה רוצה להגדיר? . עבור שאלה זו, בחר אמולטור פונקציות ואמולטור אירוח .
  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?" , בחר כן .

הפעל את אמולטור האחסון

  1. בטרמינל שלך, הפעל את אמולטור Hosting:
    firebase emulators:start --only hosting
    
    הטרמינל שלך מגיב עם היציאה שבה אתה יכול למצוא את אמולטור Hosting, למשל http://localhost:5000/ .

טרמינל המראה שהאימולטור המארחים מוכן

  1. בדפדפן שלך, נווט אל כתובת האתר באמצעות אמולטור Firebase Hosting.
  2. אם אתה רואה את השגיאה בדף האינטרנט שמתחילה כך: "Error: Firebase session cookie has incorrect..." , עליך למחוק את כל קובצי ה-Cookie שלך ​​בסביבת המארח המקומי שלך. כדי לעשות זאת, בצע את ההוראות במחק קובצי Cookie | תיעוד DevTools .

שגיאת הפעלת קובצי Cookie

מחיקת קובצי Cookie ב-DevTools

עכשיו אתה יכול לראות את אפליקציית האינטרנט הראשונית! למרות שאתה צופה באפליקציית האינטרנט בכתובת אתר של מארח מקומי, היא משתמשת בשירותי 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. באפליקציית האינטרנט, רענן את הדף ולחץ על היכנס עם 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;
}

קוד זה משתמש ב-React state hook כדי לעדכן את המשתמש כאשר הפונקציה onAuthStateChanged מציינת שיש שינוי במצב האימות.

אמת שינויים

פריסת השורש בקובץ src/app/layout.js מעבדת את הכותרת ומעבירה למשתמש, אם זמין, כאביזר.

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

המשמעות היא שהרכיב <Header> מעבד נתוני משתמש, אם זמינים, במהלך זמן ריצת השרת. אם יש עדכוני אימות במהלך מחזור החיים של הדף לאחר טעינת העמוד הראשונית, המטפל onAuthStateChanged מטפל בהם.

עכשיו הגיע הזמן לבדוק את אפליקציית האינטרנט ולאמת את מה שבנית.

כדי לאמת את התנהגות האימות החדשה, בצע את השלבים הבאים:

  1. בדפדפן שלך, רענן את אפליקציית האינטרנט. שם התצוגה שלך מופיע בכותרת.
  2. צא והיכנס שוב. העמוד מתעדכן בזמן אמת ללא רענון עמוד. אתה יכול לחזור על שלב זה עם משתמשים שונים.
  3. אופציונלי: לחץ לחיצה ימנית על אפליקציית האינטרנט, בחר הצג מקור דף וחפש את שם התצוגה. הוא מופיע במקור ה-HTML הגולמי שהוחזר מהשרת.

7. הצג מידע על המסעדה

אפליקציית האינטרנט כוללת נתונים מדומים עבור מסעדות וביקורות.

הוסף מסעדה אחת או יותר

כדי להוסיף נתוני מסעדות מדומים למסד הנתונים המקומי של Cloud Firestore, בצע את השלבים הבאים:

  1. באפליקציית האינטרנט, בחר 2cf67d488d8e6332.png > הוסף מסעדות לדוגמה .
  2. במסוף Firebase בדף Firestore Database , בחר מסעדות . אתה רואה את המסמכים ברמה העליונה באוסף המסעדות, שכל אחד מהם מייצג מסעדה.
  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 והשבת את JavaScript .

השבת את JavaScipt ב-DevTools

  1. רענן את אפליקציית האינטרנט. רשימות המסעדות עדיין נטענות. פרטי המסעדה מוחזרים בתגובת השרת. כאשר JavaScript מופעל, מידע המסעדה עובר לחות באמצעות קוד ה-JavaScript בצד הלקוח.
  2. ב-DevTools, הפעל מחדש את JavaScript .

האזינו לעדכוני מסעדות עם מאזיני תמונת מצב של 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 מספקת ממשק API נוח לגישה לנתוני טופס, כגון data.get("text") כדי לקבל את ערך הטקסט ממטען הגשת הטופס.

כדי להשתמש בפעולת שרת Next.js כדי לעבד את שליחת טופס הבדיקה, בצע את השלבים הבאים:

  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, ומעדכן את כתובת האתר של התמונה במסמך 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 והעלה תמונה ממערכת הקבצים שלך. התמונה שלך עוזבת את הסביבה המקומית שלך ומועלת ל-Cloud Storage. התמונה מופיעה מיד לאחר העלאתה.
  3. נווט אל Cloud Storage for Firebase.
  4. נווט אל התיקיה שמייצגת את המסעדה. התמונה שהעלית קיימת בתיקייה.

6cf3f9e2303c931c.png

10. מסקנה

מזל טוב! למדת כיצד להשתמש ב-Firebase כדי להוסיף תכונות ופונקציונליות לאפליקציית Next.js. באופן ספציפי, השתמשת בדברים הבאים:

למד עוד

,

1. לפני שמתחילים

במעבדת קוד זה תלמדו כיצד לשלב את Firebase עם אפליקציית אינטרנט של Next.js בשם Friendly Eats, שהיא אתר לביקורות מסעדות.

אפליקציית האינטרנט של Friendly Eats

אפליקציית האינטרנט שהושלמה מציעה תכונות שימושיות המדגימות כיצד Firebase יכול לעזור לך לבנות אפליקציות Next.js. תכונות אלה כוללות את הדברים הבאים:

  • כניסה עם Google ופונקציונליות יציאה: אפליקציית האינטרנט שהושלמה מאפשרת לך להיכנס עם Google ולצאת. התחברות וההתמדה של המשתמש מנוהלות לחלוטין באמצעות אימות Firebase .
  • תמונות: אפליקציית האינטרנט שהושלמה מאפשרת למשתמשים שנכנסו להעלות תמונות של מסעדות. נכסי תמונה מאוחסנים ב- Cloud Storage for Firebase . Firebase JavaScript SDK מספק כתובת אתר ציבורית לתמונות שהועלו. כתובת האתר הציבורית הזו מאוחסנת לאחר מכן במסמך המסעדה הרלוונטי ב- Cloud Firestore .
  • ביקורות: אפליקציית האינטרנט שהושלמה מאפשרת למשתמשים שנכנסו לחשבון לפרסם ביקורות על מסעדות המורכבות מדירוג כוכבים והודעה מבוססת טקסט. מידע סקירה מאוחסן ב-Cloud Firestore.
  • מסננים: אפליקציית האינטרנט שהושלמה מאפשרת למשתמשים שנכנסו לסנן את רשימת המסעדות על סמך קטגוריה, מיקום ומחיר. ניתן גם להתאים אישית את שיטת המיון שבה נעשה שימוש. הגישה לנתונים מתבצעת מ-Cloud Firestore, ושאילתות Firestore מוחלות על סמך המסננים שבהם נעשה שימוש.

דרישות מוקדמות

  • ידע ב-Next.js וב-JavaScript

מה תלמד

  • כיצד להשתמש ב-Firebase עם נתב האפליקציה Next.js ועיבוד בצד השרת.
  • כיצד להתמיד בתמונות ב-Cloud Storage for Firebase.
  • כיצד לקרוא ולכתוב נתונים במסד נתונים של Cloud Firestore.
  • כיצד להשתמש בכניסה עם Google עם Firebase JavaScript SDK.

מה אתה צריך

  • Git
  • ערכת הפיתוח של Java
  • גרסה יציבה עדכנית של Node.js
  • דפדפן לבחירתך, כגון Google Chrome
  • סביבת פיתוח עם עורך קוד ומסוף
  • חשבון 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 שלך ​​ולאחר מכן לחץ על אפשר .

3. הגדר את פרויקט Firebase שלך

בחלק זה, תגדיר פרויקט Firebase ותשייך אליו אפליקציית אינטרנט של Firebase. כמו כן, תגדיר את שירותי Firebase המשמשים את אפליקציית האינטרנט לדוגמה.

צור פרויקט Firebase

  1. במסוף Firebase , לחץ על צור פרויקט .
  2. בתיבת הטקסט הזן את שם הפרויקט שלך , הזן את FriendlyEats Codelab (או שם פרויקט לבחירתך), ולאחר מכן לחץ על המשך .
  3. עבור מעבדת קוד זה, אינך זקוק ל-Google Analytics, אז כבה את האפשרות הפעל את Google Analytics עבור פרויקט זה .
  4. לחץ על צור פרויקט .
  5. המתן להקצאת הפרוייקט שלך ולאחר מכן לחץ על המשך .
  6. בפרויקט Firebase שלך, עבור אל הגדרות פרויקט . שים לב לזהות הפרויקט שלך כי אתה צריך אותו מאוחר יותר. מזהה ייחודי זה הוא האופן שבו הפרויקט שלך מזוהה (לדוגמה, ב-CLI של Firebase).

הוסף אפליקציית אינטרנט לפרויקט Firebase שלך

  1. נווט אל סקירת הפרויקט שלך בפרויקט Firebase שלך ​​ולאחר מכן לחץ e41f2efdd9539c31.png אינטרנט .
  2. בתיבת הטקסט של כינוי אפליקציה , הזן כינוי אפליקציה בלתי נשכח, כגון My Next.js app .
  3. בחר בתיבת הסימון הגדר גם אירוח Firebase עבור אפליקציה זו .
  4. לחץ על הרשמה אפליקציה > הבא > הבא > המשך למסוף .

שדרג את תוכנית התמחור שלך ב-Firebase

כדי להשתמש במסגרות אינטרנט, פרויקט Firebase שלך ​​צריך להיות בתוכנית התמחור של Blaze , מה שאומר שהוא משויך לחשבון Cloud Billing .

עם זאת, שים לב שהשלמת Codelab זה לא אמורה לגרור חיובים בפועל.

כדי לשדרג את הפרויקט שלך לתוכנית Blaze, בצע את השלבים הבאים:

  1. במסוף Firebase, בחר לשדרג את התוכנית שלך .
  2. בתיבת הדו-שיח, בחר את תוכנית Blaze ולאחר מכן עקוב אחר ההוראות שעל המסך כדי לשייך את הפרויקט שלך לחשבון Cloud Billing.
    אם היית צריך ליצור חשבון Cloud Billing, ייתכן שיהיה עליך לנווט חזרה לזרימת השדרוג במסוף Firebase כדי להשלים את השדרוג.

הגדר שירותי Firebase במסוף Firebase

הגדר אימות

  1. במסוף Firebase, נווט אל אימות .
  2. לחץ על התחל .
  3. בעמודה ספקים נוספים , לחץ על Google > הפעל .
  4. בתיבת הטקסט שם פונה לציבור עבור פרויקט , הזן שם בלתי נשכח, כגון My Next.js app .
  5. מהתפריט הנפתח דוא"ל תמיכה לפרויקט , בחר את כתובת הדוא"ל שלך.
  6. לחץ על שמור .

הגדר את Cloud Firestore

  1. במסוף Firebase, נווט אל Firestore .
  2. לחץ על צור מסד נתונים > התחל במצב בדיקה > הבא .
    בהמשך מעבדת הקוד הזה, תוסיף כללי אבטחה כדי לאבטח את הנתונים שלך. אין להפיץ או לחשוף אפליקציה בפומבי מבלי להוסיף כללי אבטחה עבור מסד הנתונים שלך .
  3. השתמש במיקום ברירת המחדל או בחר מיקום לבחירתך.
    עבור אפליקציה אמיתית, אתה רוצה לבחור מיקום שקרוב למשתמשים שלך. שימו לב שלא ניתן לשנות את המיקום הזה מאוחר יותר, והוא גם יהיה אוטומטית המיקום של דלי ברירת המחדל של Cloud Storage (השלב ​​הבא).
  4. לחץ על בוצע .

הגדר אחסון בענן עבור Firebase

  1. במסוף Firebase, נווט אל אחסון .
  2. לחץ על התחל > התחל במצב בדיקה > הבא .
    בהמשך מעבדת הקוד הזה, תוסיף כללי אבטחה כדי לאבטח את הנתונים שלך. אין להפיץ או לחשוף אפליקציה בפומבי מבלי להוסיף כללי אבטחה עבור דלי האחסון שלך.
  3. המיקום של הדלי שלך כבר אמור להיות נבחר (עקב הגדרת Firestore בשלב הקודם).
  4. לחץ על בוצע .

4. סקור את בסיס הקוד של המתחיל

בחלק זה תבדוק כמה תחומים בבסיס הקוד המתנע של האפליקציה אליהם תוסיף פונקציונליות בקודלב זה.

תיקיה ומבנה קבצים

הטבלה הבאה מכילה סקירה של התיקיה ומבנה הקבצים של האפליקציה:

תיקיות וקבצים

תיאור

src/components

תגובה רכיבים למסננים, כותרות, פרטי מסעדה וביקורות

src/lib

פונקציות שירות שאינן בהכרח קשורות להגיב או הבא. Js

src/lib/firebase

קוד ספציפי ל- Firebase ותצורת Firebase

public

נכסים סטטיים באפליקציית האינטרנט, כמו סמלים

src/app

ניתוב עם נתב האפליקציה הבא. Js

src/app/restaurant

מטפל מסלול API

package.json ו- package-lock.json

תלות בפרויקט עם NPM

next.config.js

תצורה ספציפית. Js (פעולות שרת מופעלות )

jsconfig.json

תצורת שירות שפה של JavaScript

רכיבי שרת ולקוח

האפליקציה היא אפליקציית אינטרנט הבאה. JS המשתמשת בנתב האפליקציה . עיבוד שרת משמש בכל האפליקציה. לדוגמה, קובץ src/app/page.js הוא רכיב שרת האחראי לדף הראשי. קובץ ה- src/components/RestaurantListings.jsx הוא רכיב לקוח המכונה ההנחיה "use client" בתחילת הקובץ.

ייבוא ​​הצהרות

תוכל להבחין בהצהרות יבוא כמו להלן:

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

האפליקציה משתמשת בסמל @ כדי להימנע מסלולי יבוא יחסית מגושמים ומתאפשרת על ידי כינויי נתיב .

ממשקי API ספציפיים ל- Firebase

כל קוד ה- API של Firebase עטוף בספריית src/lib/firebase . רכיבי תגובה בודדים ייבאו את הפונקציות העטופות מהספרייה src/lib/firebase , במקום לייבא ישירות פונקציות FireBase.

נתונים מדומים

נתוני מסעדה וסקירה מדומה כלולים בקובץ src/lib/randomData.js . נתונים מקובץ זה מורכבים בקוד בקובץ src/lib/fakeRestaurants.js .

5. הגדר אירוח מקומי עם אמולטור אירוח Firebase

בחלק זה תשתמש באמולטור אירוח Firebase כדי להריץ את אפליקציית האינטרנט הבאה. Js באופן מקומי.

בסוף פרק זה, אמולטור אירוח Firebase מפעיל עבורך את אפליקציית ה- Next.js, כך שאתה לא צריך להפעיל את הבא. Js בתהליך נפרד לאמולטורים.

הורד והשתמש בחשבון שירות Firebase

אפליקציית האינטרנט שתבנה ב- CodElab זה משתמשת בעיבוד צד של שרת עם Next.js.

ה- Firebase Admin SDK עבור node.js משמש כדי להבטיח שכללי האבטחה הם פונקציונליים מקוד הצד של השרת. כדי להשתמש בממשקי API במנהל Firebase, עליך להוריד ולהשתמש בחשבון שירות 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. שמור על טרמינל זה פתוח והשתמש בו להמשך Codelab זה, מכיוון שמשתנה הסביבה שלך עלול לאבד אם תתחיל במפגש מסוף חדש.
    אם אתה פותח מושב מסוף חדש, עליך לשחזר מחדש את הפקודה הקודמת.

הוסף את תצורת 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
    • אחסון: הגדר קובץ כללי אבטחה לאחסון ענן
    • אמולטורים: הקימו אמולטורים מקומיים למוצרי Firebase
  4. בחר השתמש בפרויקט קיים ואז הזן את מזהה הפרויקט שציינת בעבר.
  5. בחר את ערכי ברירת המחדל עבור כל השאלות הבאות עד שתגיע לשאלה באיזה אזור תרצה לארח תוכן בצד השרת, אם ישים? . הטרמינל מציג הודעה שהיא מגלה בסיס קוד קיים. Js בספריה הנוכחית.
  6. לשאלה באיזה אזור תרצה לארח תוכן בצד השרת, אם ישים? , בחר את המיקום שבחרת בעבר לאחסון Firestore ו- Cloud.
  7. בחר את ערכי ברירת המחדל עבור כל השאלות הבאות עד שתגיע לשאלה אילו אמולטורים של Firebase אתה רוצה להגדיר? . לשאלה זו, בחר פונקציות אמולטור ואירוח אמולטור .
  8. בחר את ערכי ברירת המחדל עבור כל השאלות האחרות.

לפרוס כללי אבטחה

לקוד כבר יש קבוצות של כללי אבטחה עבור Firestore ולאחסון ענן עבור 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?" , בחר כן .

התחל את אמולטור האירוח

  1. בטרמינל שלך, הפעל את אמולטור האירוח:
    firebase emulators:start --only hosting
    
    המסוף שלך מגיב עם היציאה בה תוכל למצוא את אמולטור האירוח, למשל http: // localhost: 5000/ .

מסוף מראה כי אמולטור האירוח מוכן

  1. בדפדפן שלך, נווט לכתובת האתר עם אמולטור אירוח Firebase.
  2. אם אתה רואה את השגיאה בדף האינטרנט שמתחילה כך: "Error: Firebase session cookie has incorrect..." , אתה צריך למחוק את כל העוגיות שלך בסביבת ה- LocalHost שלך. לשם כך, עקוב אחר ההוראות במחיקת עוגיות | תיעוד DevTools .

שגיאת מושב עוגיות

מחיקת עוגיות ב- Devtools

עכשיו אתה יכול לראות את אפליקציית האינטרנט הראשונית! למרות שאתה צופה באפליקציית האינטרנט בכתובת URL של Localhost, היא משתמשת בשירותי Firebase אמיתיים שהגדרת בקונסולה שלך.

6. הוסף אימות לאפליקציית האינטרנט

בחלק זה אתה מוסיף אימות לאפליקציית האינטרנט כך שתוכל להיכנס אליו.

ליישם את פונקציות הכניסה וה- RINTOUT

  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 הבא:

API של Firebase

תיאור

GoogleAuthProvider

יוצר מופע של ספק אימות של גוגל.

signInWithPopup

מתחיל זרימת אימות מבוססת דו-שיח.

auth.signOut

יוצא למשתמש.

בקובץ src/components/Header.jsx , הקוד כבר קורא לפונקציות signInWithGoogle ו- signOut .

  1. באפליקציית האינטרנט, רענן את הדף ולחץ על היכנס עם גוגל . אפליקציית האינטרנט אינה מתעדכנת, ולכן לא ברור אם כניסה הצליחה.

הירשם לשינויי אימות

כדי להירשם לשינויי אימות, בצע את הצעדים הבאים:

  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;
}

קוד זה משתמש ב- React State Wook כדי לעדכן את המשתמש כאשר הפונקציה onAuthStateChanged מציינת שיש שינוי במצב האימות.

לאמת שינויים

פריסת השורש בקובץ src/app/layout.js מעבירה את הכותרת ועוברת במשתמש, אם היא זמינה, כהצעה.

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

המשמעות היא שרכיב <Header> הופך את נתוני המשתמש, אם הם זמינים, במהלך זמן ריצת השרת. אם ישנם עדכוני אימות במהלך מחזור החיים של העמוד לאחר עומס העמוד הראשוני, המטפל onAuthStateChanged מטפל בהם.

עכשיו הגיע הזמן לבדוק את אפליקציית האינטרנט ולאמת את מה שבנית.

כדי לאמת את התנהגות האימות החדשה, בצע את הצעדים הבאים:

  1. בדפדפן שלך, רענן את אפליקציית האינטרנט. שם התצוגה שלך מופיע בכותרת.
  2. צאו ונכנסו שוב. העמוד מתעדכן בזמן אמת ללא רענון של דף. אתה יכול לחזור על שלב זה עם משתמשים שונים.
  3. אופציונלי: לחץ באמצעות לחצן העכבר הימני על אפליקציית האינטרנט, בחר מקור בדף תצוגה וחפש את שם התצוגה. זה מופיע במקור HTML הגולמי שהוחזר מהשרת.

7. צפה במידע על המסעדות

אפליקציית האינטרנט כוללת נתוני מדומה למסעדות וביקורות.

הוסף מסעדה אחת או יותר

כדי להכניס נתוני מסעדה מדומים למסד הנתונים המקומי שלך בענן Firestore, בצע את הצעדים הבאים:

  1. באפליקציית האינטרנט, בחר 2cf67d488d8e6332.png > הוסף מסעדות לדוגמא .
  2. במסוף Firebase בדף מסד הנתונים של Firestore , בחר מסעדות . אתה רואה את המסמכים ברמה העליונה באוסף המסעדות, שכל אחד מהם מייצג מסעדה.
  3. לחץ על כמה מסמכים כדי לחקור את המאפיינים של מסמך מסעדה.

להציג את רשימת המסעדות

למסד הנתונים של Cloud Firestore שלך ​​יש כעת מסעדות שאפליקציית האינטרנט הבאה. 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. רענן את אפליקציית האינטרנט. תמונות מסעדה מופיעות כאריחים בדף.

ודא שרשימות המסעדות נטענות בזמן ריצת השרת

באמצעות המסגרת הבאה. Js, יתכן וזה לא ברור כאשר הנתונים נטענים בזמן ריצת שרת או זמן ההפעלה בצד הלקוח.

כדי לוודא שרשימות המסעדות נטענות בזמן ריצת השרת, בצע את הצעדים הבאים:

  1. באפליקציית האינטרנט, פתחו את DevTools והשבו את JavaScript .

השבת את Javascipt ב- devtools

  1. רענן את אפליקציית האינטרנט. רשימות המסעדות עדיין נטענות. מידע על המסעדות מוחזר בתגובת השרת. כאשר JavaScript מופעל, מידע על המסעדה מתייבש דרך קוד JavaScript בצד הלקוח.
  2. ב- Devtools, הפעל מחדש את JavaScript .

האזן לעדכוני מסעדה עם מאזיני תמונת המצב של ענן Firestore

בחלק הקודם ראית כיצד מערך המסעדות הראשוני נטען מקובץ src/app/page.js . קובץ ה- src/app/page.js הוא רכיב שרת ומוצג בשרת, כולל קוד ה- Firebase Data Fetching.

קובץ ה- 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

פעולת Server Next.js מספקת ממשק API נוח לגישה לנתוני טופס, כגון data.get("text") כדי לקבל את ערך הטקסט מעומס הגשת הטופס.

כדי להשתמש בפעולה של שרת הבא .

  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"),
        });
}

הוסף ביקורות למסעדה

יישמת תמיכה להגשות סקירה, אז עכשיו אתה יכול לוודא שהביקורות שלך מוכנסות לענן Firestore נכון.

כדי להוסיף סקירה ולוודא שהיא מוכנסת ל- Cloud Firestore, בצע את הצעדים הבאים:

  1. באפליקציית האינטרנט, בחר מסעדה מדף הבית.
  2. בדף המסעדה, לחץ על 3E19BEEF78BB0D0E.PNG .
  3. בחר דירוג כוכב.
  4. כתוב ביקורת.
  5. לחץ על שלח . הביקורת שלך מופיעה בראש רשימת הביקורות.
  6. ב- Cloud Firestore, חפש בחלונית המסמך הוסף את המסמך של המסעדה שסקרת ובחר אותה.
  7. בחלונית אוסף ההתחלה , בחר דירוגים .
  8. בחלונית הוסף מסמך , מצא את המסמך לבדיקה שלך כדי לוודא שהוא הוכנס כצפוי.

מסמכים באמולטור Firestore

9. שמור קבצים שעומדים על ידי משתמש מאפליקציית האינטרנט

בחלק זה אתה מוסיף פונקציונליות כך שתוכל להחליף את התמונה המשויכת למסעדה כשאתה מחובר. אתה מעלה את התמונה לאחסון Firebase, ולעדכן את כתובת האתר של התמונה במסמך 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.
  4. נווט לתיקיה המייצגת את המסעדה. התמונה שהעלית קיימת בתיקיה.

6CF3F9E2303C931C.PNG

10. מסקנה

מזל טוב! למדת כיצד להשתמש ב- Firebase כדי להוסיף תכונות ופונקציונליות לאפליקציית Next.js. באופן ספציפי השתמשת בדברים הבאים:

למד עוד