1. סקירה כללית
ב-codelab הזה תלמדו כמה מהיסודות של Firebase כדי ליצור אפליקציות אינטרנט אינטראקטיביות. תבנו אפליקציה לצ'אט של ספר אורחים ואישור השתתפות באירוע באמצעות כמה מוצרים של Firebase.
מה תלמדו
- אימות משתמשים באמצעות אימות ב-Firebase ו-FirebaseUI.
- סנכרון נתונים באמצעות Cloud Firestore.
- כתיבת כללי אבטחה ב-Firebase כדי לאבטח מסד נתונים.
מה צריך
- דפדפן לבחירתכם, כמו Chrome.
- גישה ל-stackblitz.com (לא נדרש חשבון או כניסה).
- חשבון Google, כמו חשבון Gmail. מומלץ להשתמש בחשבון האימייל שבו אתם כבר משתמשים לחשבון GitHub. כך תוכלו להשתמש בתכונות מתקדמות ב-StackBlitz.
- קוד לדוגמה של ה-codelab. הסבר על קבלת הקוד מופיע בשלב הבא.
2. קבלת קוד ההתחלה
ב-codelab הזה, תיצרו אפליקציה באמצעות StackBlitz, כלי עריכה אונליין שמשולבים בו כמה תהליכי עבודה של Firebase. לא צריך להתקין תוכנה או ליצור חשבון מיוחד ב-StackBlitz.
ב-StackBlitz אפשר לשתף פרויקטים עם אחרים. אנשים אחרים שיש להם את כתובת ה-URL של פרויקט StackBlitz יכולים לראות את הקוד שלכם ולבצע Fork לפרויקט, אבל הם לא יכולים לערוך את פרויקט StackBlitz.
- כדי להגיע לקוד ההתחלתי, עוברים לכתובת ה-URL הבאה: https://stackblitz.com/edit/firebase-gtk-web-start
- בחלק העליון של דף StackBlitz, לוחצים על Fork:
עכשיו יש לכם עותק של קוד ההתחלה כפרויקט StackBlitz משלכם, עם שם ייחודי וכתובת URL ייחודית. כל הקבצים והשינויים שלכם נשמרים בפרויקט הזה ב-StackBlitz.
3. עריכת פרטי האירוע
חומרי ההתחלה של ה-codelab הזה מספקים מבנה מסוים לאפליקציית האינטרנט, כולל כמה גיליונות סגנונות וכמה מאגרי HTML לאפליקציה. בהמשך ה-codelab, תגדירו את המאגרים האלה ב-Firebase.
כדי להתחיל, נסביר על הממשק של StackBlitz.
- ב-StackBlitz, פותחים את הקובץ
index.html
. - מאתרים את
event-details-container
ואתdescription-container
ומנסים לערוך כמה פרטים של אירוע.
כשעורכים את הטקסט, טעינת הדף האוטומטית ב-StackBlitz מציגה את פרטי האירוע החדשים. מגניב, נכון?
<!-- ... -->
<div id="app">
<img src="..." />
<section id="event-details-container">
<h1>Firebase Meetup</h1>
<p><i class="material-icons">calendar_today</i> October 30</p>
<p><i class="material-icons">location_city</i> San Francisco</p>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<section id="description-container">
<h2>What we'll be doing</h2>
<p>Join us for a day full of Firebase Workshops and Pizza!</p>
</section>
</div>
<!-- ... -->
תצוגה מקדימה של האפליקציה אמורה להיראות כך:
תצוגה מקדימה של האפליקציה
4. יצירה והגדרה של פרויקט Firebase
הצגת פרטי האירוע היא דבר טוב למשתתפים, אבל הצגת האירועים בלבד לא מועילה לאף אחד. בשלב הבא, נוסיף לאפליקציה פונקציונליות דינמית. כדי לעשות את זה, צריך לקשר את Firebase לאפליקציה. כדי להתחיל להשתמש ב-Firebase, צריך ליצור ולהגדיר פרויקט ב-Firebase.
יצירת פרויקט Firebase
- נכנסים למסוף Firebase באמצעות חשבון Google.
- לוחצים על הלחצן ליצירת פרויקט חדש ומזינים שם לפרויקט (לדוגמה,
Firebase-Web-Codelab
). - לוחצים על המשך.
- אם מוצגת בקשה לעשות זאת, קוראים ומאשרים את התנאים של Firebase, ואז לוחצים על המשך.
- (אופציונלי) מפעילים את העזרה מבוססת-AI במסוף Firebase (שנקראת Gemini ב-Firebase).
- ב-codelab הזה לא צריך להשתמש ב-Google Analytics, ולכן משביתים את האפשרות Google Analytics.
- לוחצים על יצירת פרויקט, מחכים שהפרויקט יוקצה ולוחצים על המשך.
מידע נוסף על פרויקטים ב-Firebase זמין במאמר הסבר על פרויקטים ב-Firebase.
הפעלה והגדרה של מוצרי Firebase במסוף
האפליקציה שאתם בונים משתמשת בכמה מוצרים של Firebase שזמינים לאפליקציות אינטרנט:
- אימות ב-Firebase וממשק המשתמש של Firebase כדי לאפשר למשתמשים להיכנס לאפליקציה בקלות.
- Cloud Firestore כדי לשמור נתונים מובנים בענן ולקבל הודעה מיידית כשמתבצעים שינויים בנתונים.
- כללי אבטחה של Firebase כדי לאבטח את מסד הנתונים.
כדי להשתמש בחלק מהמוצרים האלה, צריך לבצע הגדרה מיוחדת או להפעיל אותם באמצעות מסוף Firebase.
הפעלת כניסה באמצעות אימייל ב-Firebase Authentication
כדי לאפשר למשתמשים להיכנס לאפליקציית האינטרנט, תשתמשו בשיטת הכניסה אימייל/סיסמה ב-codelab הזה:
- בחלונית הימנית של מסוף Firebase, לוחצים על Build (פיתוח) > Authentication (אימות). לוחצים על שנתחיל?. עכשיו אתם נמצאים במרכז הבקרה של האימות, שבו אפשר לראות את המשתמשים שנרשמו, להגדיר ספקי כניסה ולנהל את ההגדרות.
- בוחרים בכרטיסייה Sign-in method (או לוחצים כאן כדי לעבור ישירות לכרטיסייה).
- לוחצים על אימייל/סיסמה באפשרויות של הספק, מעבירים את המתג למצב הפעלה ואז לוחצים על שמירה.
הגדרה של Cloud Firestore
אפליקציית האינטרנט משתמשת ב-Cloud Firestore כדי לשמור הודעות בצ'אט ולקבל הודעות חדשות בצ'אט.
כך מגדירים את Cloud Firestore בפרויקט Firebase:
- בחלונית הימנית במסוף Firebase, מרחיבים את Build ובוחרים באפשרות Firestore database.
- לוחצים על יצירת מסד נתונים.
- משאירים את הערך
(default)
בשדה מזהה מסד הנתונים. - בוחרים מיקום למסד הנתונים ולוחצים על הבא.
באפליקציה אמיתית, כדאי לבחור מיקום שקרוב למשתמשים. - לוחצים על התחלה במצב בדיקה. קוראים את כתב הוויתור בנוגע לכללי האבטחה.
בהמשך ה-codelab הזה, תוסיפו כללי אבטחה כדי לאבטח את הנתונים. אל תפיצו או תחשפו אפליקציה באופן ציבורי בלי להוסיף כללי אבטחה למסד הנתונים. - לוחצים על יצירה.
5. הוספה והגדרה של Firebase
אחרי שיצרתם את פרויקט Firebase והפעלתם כמה שירותים, צריך להגדיר בקוד שאתם רוצים להשתמש ב-Firebase, וגם לציין באיזה פרויקט Firebase אתם רוצים להשתמש.
הוספת ספריות Firebase
כדי להשתמש ב-Firebase באפליקציה, צריך להוסיף את ספריות Firebase לאפליקציה. יש כמה דרכים לעשות את זה, כפי שמתואר במסמכי התיעוד של Firebase. לדוגמה, אפשר להוסיף את הספריות מ-CDN של Google, או להתקין אותן באופן מקומי באמצעות npm ואז לארוז אותן באפליקציה אם משתמשים ב-Browserify.
StackBlitz מספקת חבילה אוטומטית, כך שאפשר להוסיף את ספריות Firebase באמצעות הצהרות ייבוא. תשתמשו בגרסאות המודולריות (גרסה 9) של הספריות, שעוזרות להקטין את הגודל הכולל של דף האינטרנט באמצעות תהליך שנקרא 'הסרת קוד שלא בשימוש'. במסמכי התיעוד מפורט מידע נוסף על ערכות SDK מודולריות.
כדי ליצור את האפליקציה הזו, משתמשים בספריות Firebase Authentication, FirebaseUI ו-Cloud Firestore. ב-codelab הזה, הצהרות הייבוא הבאות כבר כלולות בחלק העליון של הקובץ index.js
, ואנחנו נייבא עוד שיטות מכל ספריית Firebase בהמשך:
// Import stylesheets
import './style.css';
// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';
// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';
import * as firebaseui from 'firebaseui';
איך מוסיפים אפליקציית אינטרנט של Firebase לפרויקט Firebase
- במסוף Firebase, לוחצים על Project Overview (סקירת הפרויקט) בפינה הימנית העליונה כדי לעבור לדף הסקירה הכללית של הפרויקט.
- במרכז הדף 'סקירה כללית' של הפרויקט, לוחצים על סמל האינטרנט
כדי ליצור אפליקציית אינטרנט חדשה של Firebase.
- רושמים את האפליקציה עם הכינוי Web App.
- במסגרת ה-codelab הזה, אל תסמנו את התיבה לצד Also set up Firebase Hosting for this app (הגדרת אירוח ב-Firebase גם לאפליקציה הזו). בשלב הזה תשתמשו בחלונית התצוגה המקדימה של StackBlitz.
- לוחצים על Register app (רישום האפליקציה).
- מעתיקים את אובייקט ההגדרה של Firebase ללוח.
- לוחצים על Continue to console (המשך למסוף). מוסיפים את אובייקט ההגדרה של Firebase לאפליקציה:
- חוזרים ל-StackBlitz ועוברים לקובץ
index.js
. - מאתרים את שורת ההערה
Add Firebase project configuration object here
ומדביקים את קטע ההגדרות ממש מתחת להערה. - מוסיפים את הקריאה לפונקציה
initializeApp
כדי להגדיר את Firebase באמצעות ההגדרה הייחודית של פרויקט Firebase.// ... // Add Firebase project configuration object here const firebaseConfig = { apiKey: "random-unique-string", authDomain: "your-projectId.firebaseapp.com", databaseURL: "https://your-projectId.firebaseio.com", projectId: "your-projectId", storageBucket: "your-projectId.firebasestorage.app", messagingSenderId: "random-unique-string", appId: "random-unique-string", }; // Initialize Firebase initializeApp(firebaseConfig);
6. הוספת כניסה של משתמש (אישור השתתפות)
אחרי שמוסיפים את Firebase לאפליקציה, אפשר להגדיר לחצן לאישור השתתפות שרושם אנשים באמצעות Firebase Authentication.
אימות משתמשים באמצעות כניסה עם כתובת אימייל ו-FirebaseUI
תצטרכו להוסיף לחתימה לחצן לאישור השתתפות, שיבקש מהמשתמש להיכנס באמצעות כתובת האימייל שלו. אפשר לעשות את זה על ידי קישור של FirebaseUI ללחצן אישור הגעה.FirebaseUI היא ספרייה שמספקת ממשק משתמש מוכן מראש על גבי Firebase Auth.
FirebaseUI דורש הגדרה (אפשרויות ההגדרה מפורטות במסמכי התיעוד) שמבצעת שני דברים:
- הפונקציה הזו מציינת ל-FirebaseUI שרוצים להשתמש בשיטת הכניסה Email/Password.
- מטפלת בקריאה החוזרת לכניסה מוצלחת ומחזירה false כדי למנוע הפניה אוטומטית. אתם לא רוצים שהדף יתרענן כי אתם בונים אפליקציית אינטרנט של דף יחיד.
הוספת הקוד לאתחול FirebaseUI Auth
- ב-StackBlitz, עוברים לקובץ
index.js
. - בחלק העליון, מאתרים את הצהרת הייבוא
firebase/auth
, ואז מוסיפים אתgetAuth
ואתEmailAuthProvider
, כך:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore';
- שומרים הפניה לאובייקט האימות מיד אחרי
initializeApp
, כך:initializeApp(firebaseConfig); auth = getAuth();
- שימו לב שההגדרה של FirebaseUI כבר מופיעה בקוד ההתחלתי. הוא כבר מוגדר לשימוש בספק אימות האימייל.
- בתחתית הפונקציה
main()
ב-index.js
, מוסיפים את הצהרת האתחול של FirebaseUI, כך:async function main() { // ... // Initialize the FirebaseUI widget using Firebase const ui = new firebaseui.auth.AuthUI(auth); } main();
הוספת לחצן לאישור השתתפות ל-HTML
- ב-StackBlitz, עוברים לקובץ
index.html
. - מוסיפים את קוד ה-HTML של לחצן אישור ההגעה בתוך התג
event-details-container
, כמו בדוגמה שלמטה.
חשוב להשתמש באותם ערכיid
שמוצגים בהמשך, כי בקובץindex.js
כבר יש hooks למזהים הספציפיים האלה.
שימו לב שבקובץindex.html
יש מאגר תגים עם המזההfirebaseui-auth-container
. זה המזהה שתעבירו ל-FirebaseUI כדי לשמור את פרטי הכניסה שלכם. תצוגה מקדימה של אפליקציה<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- מגדירים מאזין על לחצן האישור להשתתפות באירוע ומפעילים את פונקציית ההתחלה של FirebaseUI. הפעולה הזו אומרת ל-FirebaseUI שאתם רוצים לראות את חלון הכניסה.
מוסיפים את הקוד הבא לחלק התחתון של הפונקציהmain()
ב-index.js
:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
בדיקת הכניסה לאפליקציה
- בחלון התצוגה המקדימה של StackBlitz, לוחצים על הלחצן לאישור ההגעה כדי להיכנס לאפליקציה.
- ב-codelab הזה, אפשר להשתמש בכל כתובת אימייל, אפילו בכתובת אימייל מזויפת, כי לא מגדירים שלב לאימות כתובת אימייל.
- אם מופיעה הודעת שגיאה עם הכיתוב
auth/operation-not-allowed
אוThe given sign-in provider is disabled for this Firebase project
, צריך לוודא שהפעלתם את התחברות באמצעות אימייל וסיסמה כספק התחברות במסוף Firebase.
- נכנסים אל לוח הבקרה של אימות במסוף Firebase. בכרטיסייה משתמשים אמורים להופיע פרטי החשבון שהזנתם כדי להיכנס לאפליקציה.
הוספת מצב אימות לממשק המשתמש
בשלב הבא, מוודאים שממשק המשתמש משקף את העובדה שאתם מחוברים לחשבון.
תשתמשו בפונקציית הקריאה החוזרת (callback) של מאזין המצב של אימות ב-Firebase, שמקבלת הודעה בכל פעם שסטטוס הכניסה של המשתמש משתנה. אם יש כרגע משתמש מחובר, האפליקציה תהפוך את הלחצן 'אישור השתתפות' ללחצן 'יציאה'.
- ב-StackBlitz, עוברים לקובץ
index.js
. - בחלק העליון, מאתרים את הצהרת הייבוא
firebase/auth
, ואז מוסיפים אתsignOut
ואתonAuthStateChanged
, כך:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import {} from 'firebase/firestore';
- מוסיפים את הקוד הבא לתחתית הפונקציה
main()
:async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } }); } main();
- במאזין ללחצן, בודקים אם יש משתמש נוכחי ומנתקים אותו מהחשבון. כדי לעשות את זה, מחליפים את
startRsvpButton.addEventListener
הנוכחי בקוד הבא:// ... // Called when the user clicks the RSVP button startRsvpButton.addEventListener('click', () => { if (auth.currentUser) { // User is signed in; allows user to sign out signOut(auth); } else { // No user is signed in; allows user to sign in ui.start('#firebaseui-auth-container', uiConfig); } });
עכשיו הלחצן באפליקציה אמור להציג את האפשרות התנתקות, וכשלוחצים עליו הוא אמור לחזור לאפשרות אישור השתתפות.
תצוגה מקדימה של האפליקציה
7. כתיבת הודעות ל-Cloud Firestore
זה נהדר לדעת שהמשתמשים מגיעים, אבל כדאי לתת לאורחים עוד משהו לעשות באפליקציה. מה אם הם יוכלו להשאיר הודעות בספר האורחים? הם יכולים לשתף למה הם מתרגשים להגיע או את מי הם מקווים לפגוש.
כדי לאחסן את ההודעות בצ'אט שהמשתמשים כותבים באפליקציה, תשתמשו ב-Cloud Firestore.
מודל נתונים
Cloud Firestore הוא מסד נתונים מסוג NoSQL, והנתונים שמאוחסנים בו מחולקים לקולקציות, מסמכים, שדות וקולקציות משנה. כל הודעה בצ'אט תישמר כמסמך באוסף ברמה העליונה שנקרא guestbook
.
הוספת הודעות ל-Firestore
בקטע הזה מוסיפים את הפונקציונליות שמאפשרת למשתמשים לכתוב הודעות חדשות למסד הנתונים. קודם מוסיפים את קוד ה-HTML של רכיבי ממשק המשתמש (שדה ההודעה ולחצן השליחה). לאחר מכן מוסיפים את הקוד שמקשר בין הרכיבים האלה למסד הנתונים.
כדי להוסיף את רכיבי ממשק המשתמש של שדה הודעה ולחצן שליחה:
- ב-StackBlitz, עוברים לקובץ
index.html
. - מחפשים את התג
guestbook-container
ומוסיפים את קוד ה-HTML הבא כדי ליצור טופס עם שדה קלט להודעה ולחצן שליחה.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form id="leave-message"> <label>Leave a message: </label> <input type="text" id="message"> <button type="submit"> <i class="material-icons">send</i> <span>SEND</span> </button> </form> </section> <!-- ... -->
תצוגה מקדימה של האפליקציה
משתמש שלוחץ על הלחצן SEND (שליחה) יפעיל את קטע הקוד שבהמשך. התוכן של שדה הקלט של ההודעה מתווסף לאוסף guestbook
של מסד הנתונים. באופן ספציפי, השיטה addDoc
מוסיפה את תוכן ההודעה למסמך חדש (עם מזהה שנוצר באופן אוטומטי) לאוסף guestbook
.
- ב-StackBlitz, עוברים לקובץ
index.js
. - בחלק העליון, מאתרים את הצהרת הייבוא
firebase/firestore
ומוסיפים אתgetFirestore
,addDoc
ו-collection
, כך:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, addDoc, collection } from 'firebase/firestore';
- עכשיו נשמור הפניה לאובייקט
db
של Firestore מיד אחריinitializeApp
:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore();
- בתחתית הפונקציה
main()
, מוסיפים את הקוד הבא.
שימו לב ש-auth.currentUser.uid
הוא הפניה למזהה הייחודי שנוצר באופן אוטומטי ומוקצה על ידי אימות ב-Firebase לכל המשתמשים שמחוברים לחשבון.async function main() { // ... // Listen to the form submission form.addEventListener('submit', async e => { // Prevent the default form redirect e.preventDefault(); // Write a new message to the database collection "guestbook" addDoc(collection(db, 'guestbook'), { text: input.value, timestamp: Date.now(), name: auth.currentUser.displayName, userId: auth.currentUser.uid }); // clear message input field input.value = ''; // Return false to avoid redirect return false; }); } main();
הצגת ספר האורחים רק למשתמשים שמחוברים לחשבון
אתם לא רוצים שכל אחד יוכל לראות את הצ'אט של המשתתפים. אחת הדרכים לאבטח את הצ'אט היא לאפשר רק למשתמשים שמחוברים לחשבון לראות את ספר האורחים. עם זאת, כדי להגן על מסד הנתונים של האפליקציות שלכם, כדאי להשתמש גם בכללי האבטחה של Firebase. (מידע נוסף על כללי אבטחה מופיע בהמשך ה-codelab).
- ב-StackBlitz, עוברים לקובץ
index.js
. - עורכים את
onAuthStateChanged
המאזין כדי להסתיר ולהציג את ספר האורחים.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; } });
בדיקה של שליחת הודעות
- מוודאים שנכנסתם לחשבון באפליקציה.
- כותבים הודעה, למשל "היי", ואז לוחצים על שליחה.
הפעולה הזו כותבת את ההודעה למסד הנתונים של Cloud Firestore. עם זאת, ההודעה עדיין לא תוצג באפליקציית האינטרנט בפועל, כי עדיין צריך להטמיע את אחזור הנתונים. את זה עושים אחר כך.
אבל תוכלו לראות את ההודעה החדשה במסוף Firebase.
במסוף Firebase, במרכז הבקרה של Firestore Database, אמור להופיע האוסף guestbook
עם ההודעה החדשה שהוספתם. אם תמשיכו לשלוח הודעות, אוסף הספרים לאורחים יכיל הרבה מסמכים, כמו זה:
מסוף Firebase
8. קריאת ההודעות
סנכרון הודעות
נחמד שאורחים יכולים לכתוב הודעות למסד הנתונים, אבל הם עדיין לא יכולים לראות אותן באפליקציה.
כדי להציג הודעות, צריך להוסיף מאזינים שמופעלים כשנתונים משתנים, ואז ליצור רכיב בממשק המשתמש שמציג הודעות חדשות.
מוסיפים קוד שמאזין להודעות חדשות שנוספו מהאפליקציה. קודם מוסיפים קטע ב-HTML להצגת הודעות:
- ב-StackBlitz, עוברים לקובץ
index.html
. - ב-
guestbook-container
, מוסיפים קטע חדש עם המזההguestbook
.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form><!-- ... --></form> <section id="guestbook"></section> </section> <!-- ... -->
לאחר מכן, רושמים את ה-listener שמקשיב לשינויים שבוצעו בנתונים:
- ב-StackBlitz, עוברים לקובץ
index.js
. - בחלק העליון, מאתרים את הצהרת הייבוא
firebase/firestore
ומוסיפים אתquery
,orderBy
ו-onSnapshot
, כך:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore';
- בתחתית הפונקציה
main()
, מוסיפים את הקוד הבא כדי ליצור לולאה שתעבור על כל המסמכים (הודעות בספר האורחים) במסד הנתונים. כדי לקבל מידע נוסף על מה שקורה בקוד הזה, אפשר לקרוא את המידע שמתחת לקטע הקוד.async function main() { // ... // Create query for messages const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } main();
כדי להאזין להודעות במסד הנתונים, יצרתם שאילתה באוסף ספציפי באמצעות הפונקציה collection
. הקוד שלמעלה מאזין לשינויים באוסף guestbook
, שבו מאוחסנות הודעות הצ'אט. ההודעות מסודרות גם לפי תאריך, וההודעות החדשות ביותר מוצגות למעלה באמצעות orderBy('timestamp', 'desc')
.
הפונקציה onSnapshot
מקבלת שני פרמטרים: השאילתה שבה רוצים להשתמש ופונקציית קריאה חוזרת. פונקציית הקריאה החוזרת מופעלת כשמתבצעים שינויים במסמכים שתואמים לשאילתה. לדוגמה, אם הודעה נמחקת, משתנה או מתווספת. מידע נוסף זמין במאמרי העזרה בנושא Cloud Firestore.
בדיקת סנכרון ההודעות
Cloud Firestore מסנכרן את הנתונים באופן אוטומטי ומיידי עם לקוחות שמנויים למסד הנתונים.
- ההודעות שיצרתם קודם במסד הנתונים אמורות להופיע באפליקציה. אתם יכולים לכתוב הודעות חדשות, והן אמורות להופיע באופן מיידי.
- אם פותחים את סביבת העבודה בכמה חלונות או כרטיסיות, ההודעות יסונכרנו בזמן אמת בין הכרטיסיות.
- (אופציונלי) אפשר לנסות למחוק, לשנות או להוסיף הודעות חדשות באופן ידני ישירות בקטע Database במסוף Firebase. כל השינויים אמורים להופיע בממשק המשתמש.
כל הכבוד! אתם קוראים מסמכי Cloud Firestore באפליקציה שלכם!
תצוגה מקדימה של האפליקציה
9. הגדרת כללי אבטחה בסיסיים
הגדרתם את Cloud Firestore לשימוש במצב בדיקה, כלומר מסד הנתונים שלכם פתוח לקריאה ולכתיבה. עם זאת, מומלץ להשתמש במצב בדיקה רק בשלבים מוקדמים מאוד של הפיתוח. מומלץ להגדיר כללי אבטחה למסד הנתונים במהלך פיתוח האפליקציה. האבטחה צריכה להיות חלק בלתי נפרד מהמבנה וההתנהגות של האפליקציה.
כללי אבטחה מאפשרים לכם לשלוט בגישה למסמכים ולאוספים במסד הנתונים. תחביר הכללים הגמיש מאפשר לכם ליצור כללים שתואמים לכל דבר, החל מכל פעולות הכתיבה למסד הנתונים כולו ועד לפעולות במסמך ספציפי.
אפשר לכתוב כללי אבטחה ל-Cloud Firestore במסוף Firebase:
- בקטע Build (פיתוח) במסוף Firebase, לוחצים על Firestore Database (מסד נתונים של Firestore) ואז בוחרים בכרטיסייה Rules (כללים) (או לוחצים כאן כדי לעבור ישירות לכרטיסייה Rules).
- אלה כללי האבטחה שמוגדרים כברירת מחדל, עם הגבלת זמן לגישה ציבורית של כמה שבועות מהיום.
זיהוי אוספים
קודם כל, מזהים את האוספים שהאפליקציה כותבת אליהם נתונים.
- מוחקים את הסעיף הקיים
match /{document=**}
, כך שהכללים ייראו כך:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } }
- ב-
match /databases/{database}/documents
, מזהים את האוסף שרוצים לאבטח:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. } }
הוספת כללי אבטחה
מכיוון שהשתמשתם ב-UID של האימות כשדה בכל מסמך בספר האורחים, אתם יכולים לקבל את ה-UID של האימות ולוודא שלכל מי שמנסה לכתוב למסמך יש UID תואם של אימות.
- מוסיפים את כללי הקריאה והכתיבה לקבוצת הכללים, כמו שמוצג בהמשך:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId; } } }
- לוחצים על פרסום כדי לפרוס את הכללים החדשים.עכשיו, בספר האורחים, רק משתמשים מחוברים יכולים לקרוא הודעות (כל הודעה!), אבל אפשר ליצור הודעה רק באמצעות מזהה המשתמש. בנוסף, אסור לערוך או למחוק הודעות.
הוספת כללי אימות
- מוסיפים אימות נתונים כדי לוודא שכל השדות הצפויים מופיעים במסמך:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId && "name" in request.resource.data && "text" in request.resource.data && "timestamp" in request.resource.data; } } }
- לוחצים על פרסום כדי לפרוס את הכללים החדשים.
איפוס הגדרות מסוג listener
האפליקציה מאפשרת כניסה רק למשתמשים מאומתים, ולכן צריך להעביר את השאילתה של ספר האורחים firestore
אל מאזין האימות. אחרת, יתרחשו שגיאות בהרשאות והאפליקציה תנותק כשהמשתמש יתנתק.
- ב-StackBlitz, עוברים לקובץ
index.js
. - מושכים את אוסף
onSnapshot
listener של ספר האורחים לפונקציה חדשה בשםsubscribeGuestbook
. בנוסף, צריך להקצות את התוצאות של הפונקציהonSnapshot
למשתנהguestbookListener
.
הפונקציה שלonSnapshot
listener מחזירה פונקציית ביטול הרשמה שאפשר להשתמש בה כדי לבטל את ה-listener של התמונה בהמשך.// ... // Listen to guestbook updates function subscribeGuestbook() { const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); guestbookListener = onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); }
- מוסיפים פונקציה חדשה מתחת בשם
unsubscribeGuestbook
. בודקים אם המשתנהguestbookListener
הוא לא null, ואז מפעילים את הפונקציה כדי לבטל את ה-listener.// ... // Unsubscribe from guestbook updates function unsubscribeGuestbook() { if (guestbookListener != null) { guestbookListener(); guestbookListener = null; } }
לבסוף, מוסיפים את הפונקציות החדשות לonAuthStateChanged
callback.
- לוחצים על סמל ההוספה
subscribeGuestbook()
בתחתיתif (user)
. - מוסיפים
unsubscribeGuestbook()
בתחתית ההצהרהelse
.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); } });
10. שלב בונוס: תרגול של מה שלמדתם
הקלטת סטטוס אישור ההשתתפות של משתתף
בשלב הזה, האפליקציה מאפשרת לאנשים להתחיל צ'אט אם הם מתעניינים באירוע. בנוסף, הדרך היחידה לדעת אם מישהו יגיע היא אם הוא יפרסם את זה בצ'אט. כדאי להתארגן ולעדכן את האורחים כמה אנשים מגיעים.
תוסיפו מתג להרשמה של אנשים שרוצים להשתתף באירוע, ואז תאספו נתונים על מספר האנשים שמגיעים.
- ב-StackBlitz, עוברים לקובץ
index.html
. - ב-
guestbook-container
, מוסיפים קבוצה של לחצני YES ו-NO, כך:<!-- ... --> <section id="guestbook-container"> <h2>Are you attending?</h2> <button id="rsvp-yes">YES</button> <button id="rsvp-no">NO</button> <h2>Discussion</h2> <!-- ... --> </section> <!-- ... -->
תצוגה מקדימה של האפליקציה
בשלב הבא, רושמים את מאזין הלחיצות על הלחצנים. אם המשתמש לוחץ על כן, משתמשים ב-UID של האימות כדי לשמור את התגובה במסד הנתונים.
- ב-StackBlitz, עוברים לקובץ
index.js
. - בחלק העליון, מאתרים את הצהרת הייבוא
firebase/firestore
ומוסיפים אתdoc
,setDoc
ו-where
, כך:// ... // Add the Firebase products and methods that you want to use import { getFirestore, addDoc, collection, query, orderBy, onSnapshot, doc, setDoc, where } from 'firebase/firestore';
- בחלק התחתון של הפונקציה
main()
, מוסיפים את הקוד הבא כדי להאזין לסטטוס אישור ההגעה:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { }; } main();
- לאחר מכן, יוצרים אוסף חדש בשם
attendees
ורושמים הפניה למסמך אם לוחצים על אחד מלחצני אישור ההשתתפות. מגדירים את ההפניה ל-true
או ל-false
בהתאם ללחצן שנלחץ.
קודם כל, ל-rsvpYes
: ואז, אותו הדבר לגבי// ... // Listen to RSVP responses rsvpYes.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attendi()ng: true try { await setDoc(userRef, { attending: true }); } catch (e) { console.error(e); } };
rsvpNo
, אבל עם הערךfalse
:rsvpNo.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attending: true try { await setDoc(userRef, { attending: false }); } catch (e) { console.error(e); } };
עדכון כללי האבטחה
מכיוון שכבר הגדרתם כמה כללים, הנתונים החדשים שאתם מוסיפים באמצעות הלחצנים יידחו.
אפשר להוסיף פריטים לאוסף attendees
תצטרכו לעדכן את הכללים כדי לאפשר הוספה לאוסף attendees
.
- במקרה של אוסף
attendees
, השתמשתם ב-UID של האימות כשם המסמך, ולכן אתם יכולים לאחזר אותו ולוודא ש-uid
של השולח זהה למסמך שהוא כותב. תאפשרו לכולם לקרוא את רשימת המשתתפים (כי אין בה נתונים פרטיים), אבל רק יוצר האירוע יוכל לעדכן אותה.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId; } } }
- לוחצים על פרסום כדי לפרוס את הכללים החדשים.
הוספת כללי אימות
- מוסיפים כמה כללים לאימות נתונים כדי לוודא שכל השדות הרצויים מופיעים במסמך:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId && "attending" in request.resource.data; } } }
- אל תשכחו ללחוץ על פרסום כדי להפעיל את הכללים!
(אופציונלי) עכשיו אפשר לראות את התוצאות של הלחיצה על הלחצנים. נכנסים ללוח הבקרה של Cloud Firestore במסוף Firebase.
איך קוראים את סטטוס אישור ההשתתפות
עכשיו, אחרי שהקלטתם את התשובות, נראה מי מגיע ונעדכן את הממשק.
- ב-StackBlitz, עוברים לקובץ
index.html
. - ב-
description-container
, מוסיפים רכיב חדש עם המזההnumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
לאחר מכן, רושמים את המאזין לאיסוף attendees
וסופרים את מספר התשובות YES:
- ב-StackBlitz, עוברים לקובץ
index.js
. - בחלק התחתון של הפונקציה
main()
, מוסיפים את הקוד הבא כדי להאזין לסטטוס אישור ההגעה ולספור את הלחיצות על YES.async function main() { // ... // Listen for attendee list const attendingQuery = query( collection(db, 'attendees'), where('attending', '==', true) ); const unsubscribe = onSnapshot(attendingQuery, snap => { const newAttendeeCount = snap.docs.length; numberAttending.innerHTML = newAttendeeCount + ' people going'; }); } main();
לבסוף, נדגיש את הכפתור שמתאים לסטטוס הנוכחי.
- יוצרים פונקציה שבודקת אם ל-UID הנוכחי של האימות יש רשומה באוסף
attendees
, ואז מגדירים את המחלקה של הלחצן ל-clicked
.// ... // Listen for attendee list function subscribeCurrentRSVP(user) { const ref = doc(db, 'attendees', user.uid); rsvpListener = onSnapshot(ref, doc => { if (doc && doc.data()) { const attendingResponse = doc.data().attending; // Update css classes for buttons if (attendingResponse) { rsvpYes.className = 'clicked'; rsvpNo.className = ''; } else { rsvpYes.className = ''; rsvpNo.className = 'clicked'; } } }); }
- בנוסף, ניצור פונקציה לביטול ההרשמה. הערך הזה ישמש כשהמשתמש יתנתק.
// ... function unsubscribeCurrentRSVP() { if (rsvpListener != null) { rsvpListener(); rsvpListener = null; } rsvpYes.className = ''; rsvpNo.className = ''; }
- קוראים לפונקציות מתוך מאזין האימות.
// ... // Listen to the current Auth state // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); // Subscribe to the user's RSVP subscribeCurrentRSVP(user); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none' ; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); // Unsubscribe from the guestbook collection unsubscribeCurrentRSVP(); } });
- נסו להתחבר בתור כמה משתמשים ותראו שהמספר גדל עם כל קליק נוסף על הלחצן כן.
תצוגה מקדימה של האפליקציה
11. כל הכבוד!
השתמשתם ב-Firebase כדי לבנות אפליקציית אינטרנט אינטראקטיבית בזמן אמת.
מה למדנו
- אימות ב-Firebase
- FirebaseUI
- Cloud Firestore
- כללי אבטחה של Firebase
השלבים הבאים
- רוצים לדעת עוד על תהליך העבודה למפתחים ב-Firebase? כדי ללמוד איך לבדוק את האפליקציה ולהריץ אותה באופן מקומי לחלוטין, אפשר לעיין בסדנת התכנות בנושא אמולטור Firebase.
- רוצים לקבל מידע נוסף על מוצרים אחרים של Firebase? אולי אתם רוצים לאחסן קובצי תמונה שהמשתמשים מעלים? או לשלוח התראות למשתמשים? ב-Firebase web codelab יש מידע נוסף על מוצרי Firebase רבים לאינטרנט.
- רוצים לקרוא מידע נוסף על Cloud Firestore? אולי תרצו לקרוא על אוספי משנה ועסקאות? ב-Cloud Firestore web codelab יש מדריך מפורט יותר בנושא Cloud Firestore. אפשר גם לצפות בסדרת הסרטונים הזו ב-YouTube כדי להכיר את Cloud Firestore.
מידע נוסף
- אתר Firebase: firebase.google.com
- ערוץ YouTube של Firebase
איך היה?
נשמח לקבל משוב! ממלאים את הטופס הקצר כאן.