Check out what’s new from Firebase@ Google I/O 2021, and join our alpha program for early access to the new Remote Config personalization feature. Learn more

קוד קוד אינטרנט של Firebase

במפתח קוד זה תלמד כיצד להשתמש ב- Firebase ליצירת יישומי אינטרנט בקלות על ידי יישום ופריסה של לקוח צ'אט באמצעות מוצרים ושירותים של Firebase.

3b1284f5144b54f6.png

מה תלמד

  • סנכרן נתונים באמצעות Cloud Firestore ו- Cloud Storage עבור Firebase.
  • אמת את המשתמשים שלך באמצעות אימות Firebase.
  • פרוס את אפליקציית האינטרנט שלך ב- Firebase Hosting.
  • שלח הודעות באמצעות Firebase Cloud Messaging.
  • אסוף את נתוני הביצועים של אפליקציית האינטרנט שלך.

מה אתה צריך

  • עורך IDE / טקסט לבחירתך, כגון WebStorm , Atom , Sublime או VS Code
  • מנהל החבילות npm , שמגיע בדרך כלל עם Node.js
  • מסוף / קונסולה
  • דפדפן לבחירתך, כגון Chrome
  • קוד הדוגמה של קוד הקוד (ראה את השלב הבא של קוד הקוד לקבלת הקוד).

שיבט את מאגר GitHub של קוד הקוד משורת הפקודה:

git clone https://github.com/firebase/codelab-friendlychat-web

לחלופין, אם אין לך git מותקן, אתה יכול להוריד את המאגר כקובץ ZIP .

ייבא את אפליקציית המתנע

באמצעות ה- IDE שלך, פתח או ייבא את ספריית הפעלת web-start מהמאגר המשובט. ספריית 📁 הפעלת web-start זו מכילה את קוד ההתחלה של קוד הקוד, אשר יהיה אפליקציית רשת צ'אט פונקציונאלית לחלוטין.

צור פרויקט Firebase

  1. היכנס ל- Firebase .
  2. במסוף Firebase, לחץ על הוסף פרויקט ולאחר מכן תן שם לפרויקט Firebase שלך FriendlyChat . זכור את מזהה הפרויקט עבור פרויקט Firebase שלך.
  3. בטל את הסימון של הפעל את Google Analytics לפרויקט זה
  4. לחץ על צור פרויקט .

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

  • אימות Firebase כדי לאפשר למשתמשים שלך בקלות להיכנס לאפליקציה שלך.
  • Cloud Firestore כדי לשמור נתונים מובנים בענן ולקבל התראה מיידית כאשר הנתונים משתנים.
  • אחסון ענן עבור Firebase לשמירת קבצים בענן.
  • אירוח Firebase לארח ולשרת את הנכסים שלך.
  • העברת הודעות בענן של Firebase לשליחת הודעות דחיפה והצגת התראות קופצות בדפדפן.
  • ניטור ביצועי Firebase לאיסוף נתוני ביצועי משתמשים לאפליקציה שלך.

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

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

  1. לחץ על סמל האינטרנט 58d6543a156e56f9.png כדי ליצור אפליקציית אינטרנט חדשה של Firebase.
  2. רשום את האפליקציה עם הכינוי ידידותי לצ'אט , ואז סמן את התיבה לצד הגדר גם את אירוח Firebase לאפליקציה זו . לחץ על רשום אפליקציה .
  3. לחץ על השלבים הנותרים. אינך צריך לעקוב אחר ההוראות כעת; אלה יכוסו בשלבים מאוחרים יותר של קוד קוד זה.

ea9ab0db531a104c.png

אפשר כניסה של Google לצורך אימות Firebase

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

יהיה עליך להפעיל כניסה של Google :

  1. במסוף Firebase, אתר את הקטע Build בחלונית השמאלית.
  2. לחץ על אימות , ואז לחץ על הכרטיסייה שיטת כניסה (או לחץ כאן כדי לעבור ישירות לשם).
  3. הפעל את ספק הכניסה של Google ולחץ על שמור .
  4. הגדר את השם הפונה לציבור של האפליקציה שלך ל- Chat צ'אט ידידותי ובחר דוא"ל תמיכה בפרויקט מהתפריט הנפתח.
  5. הגדר את מסך הסכמת ה- OAuth שלך במסוף הענן של Google והוסף לוגו:

d89fb3873b5d36ae.png

אפשר ענן Firestore

אפליקציית האינטרנט משתמשת ב- Cloud Firestore כדי לשמור הודעות צ'ט ולקבל הודעות צ'אט חדשות.

יהיה עליך להפעיל את Cloud Firestore:

  1. בקטע Build של קונסולת Firebase, לחץ על Firestore Database .
  2. לחץ על צור מסד נתונים בחלונית Cloud Firestore.

729991a081e7cd5.png

  1. בחר באפשרות התחל במצב בדיקה , ואז לחץ על הבא לאחר קריאת כתב ויתור על כללי האבטחה.

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

77e4986cbeaf9dee.png

  1. הגדר את המיקום שבו מאוחסנים נתוני Cloud Firestore שלך. אתה יכול להשאיר זאת כברירת מחדל או לבחור אזור קרוב אליך. לחץ על בוצע כדי לספק את Firestore.

9f2bb0d4e7ca49c7.png

אפשר אחסון בענן

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

יהיה עליך להפעיל אחסון בענן:

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

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

62f1afdcd1260127.png

  1. מיקום אחסון הענן נבחר מראש עם אותו אזור שבחרת עבור מסד הנתונים Cloud Firestore שלך. לחץ על סיום להשלמת ההתקנה.

1d7f49ebaddb32fc.png

ממשק שורת הפקודה של Firebase (CLI) מאפשר לך להשתמש ב- Firebase Hosting כדי לשרת את אפליקציית האינטרנט שלך באופן מקומי, וכן לפרוס את אפליקציית האינטרנט שלך לפרויקט Firebase שלך.

  1. התקן את ה- CLI על ידי הפעלת הפקודה npm הבאה:
npm -g install firebase-tools
  1. ודא שה- CLI הותקן כהלכה על ידי הפעלת הפקודה הבאה:
firebase --version

וודא כי הגירסה של Firebase CLI היא v4.1.0 ואילך.

  1. אשר את ה- CLI של Firebase על ידי הפעלת הפקודה הבאה:
firebase login

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

  1. ודא ששורת הפקודה שלך ניגשת לספריית web-start המקומית של האפליקציה שלך.
  2. שייך את האפליקציה שלך לפרויקט Firebase שלך ​​על ידי הפעלת הפקודה הבאה:
firebase use --add
  1. כשתתבקש, בחר את מזהה הפרויקט שלך ואז תן לכינוי לפרוייקט Firebase שלך.

כינוי שימושי אם יש לך מספר סביבות (הפקה, בימוי וכו '). עם זאת, עבור קוד קוד זה, נשתמש רק בכינוי default .

  1. עקוב אחר ההוראות הנותרות בשורת הפקודה שלך.

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

  1. במסוף מספריית הפעלת web-start , הפעל את הפקודה הבאה של Firebase CLI:
firebase serve --only hosting
  1. על שורת הפקודה שלך להציג את התגובה הבאה:
✔  hosting: Local server: http://localhost:5000

אנו משתמשים באמולטור אירוח Firebase כדי לשרת את האפליקציה שלנו באופן מקומי. אפליקציית האינטרנט אמורה להיות זמינה מ- http: // localhost: 5000 . כל הקבצים שנמצאים תחת תיקיית המשנה public מוגשים.

  1. באמצעות הדפדפן שלך, פתח את האפליקציה שלך בכתובת http: // localhost: 5000 .

אתה אמור לראות את ממשק המשתמש של אפליקציית FriendlyChat שלך, שעדיין לא מתפקד:

4c23f9475228cef4.png

האפליקציה לא יכולה לעשות שום דבר כרגע, אך בעזרתכם היא תעשה זאת בקרוב! הצבנו עבורך רק את ממשק המשתמש עד כה.

בואו עכשיו לבנות צ'אט בזמן אמת!

ייבא את ה- SDK של Firebase

עלינו לייבא את ה- SDK של Firebase לאפליקציה. ישנן מספר דרכים לעשות זאת כמתואר בתיעוד שלנו . למשל, אתה יכול לייבא את הספרייה מ- CDN שלנו. לחלופין, תוכל להתקין אותו באופן מקומי באמצעות npm, ואז לארוז אותו באפליקציה שלך אם אתה משתמש ב- Browserify.

מכיוון שאנו משתמשים ב- Firebase אירוח כדי להגיש את האפליקציה שלנו, אנו נייבא את כתובות ה- URL המקומיות שנמצאות בקובץ index.html (הממוקמות בספריית ההפעלה web-start/public/ שלך). עבור קוד קוד זה, כבר הוספנו עבורך את השורות הבאות בתחתית קובץ index.html , אך תוכל לבדוק שוב שהן קיימות.

index.html

<script src="/__/firebase/8.6.7/firebase-app.js"></script>
<script src="/__/firebase/8.6.7/firebase-auth.js"></script>
<script src="/__/firebase/8.6.7/firebase-storage.js"></script>
<script src="/__/firebase/8.6.7/firebase-messaging.js"></script>
<script src="/__/firebase/8.6.7/firebase-firestore.js"></script>
<script src="/__/firebase/8.6.7/firebase-performance.js"></script>

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

הגדר את תצורת Firebase

עלינו גם להגדיר את ה- SDK של Firebase כדי לספר לו באיזה פרויקט Firebase אנו משתמשים. מכיוון שאנו משתמשים ב- Firebase אירוח, אתה יכול לייבא סקריפט מיוחד שיעשה את התצורה הזו עבורך. שוב, עבור קוד קוד זה, כבר הוספנו עבורך את השורה הבאה בתחתית הקובץ public/index.html , אך בדוק פעמיים שהיא שם.

index.html

<script src="/__/firebase/init.js"></script>

סקריפט זה מכיל את תצורת פרויקט Firebase שלך ​​המבוססת על פרויקט Firebase שציינת קודם לכן כאשר הפעלת את השימוש ב- Firebase - firebase use --add .

אל תהסס לבדוק את הקובץ init.js כדי לראות כיצד נראית תצורת הפרויקט שלך. לשם כך, פתח את http: // localhost: 5000 / __ / firebase / init.js בדפדפן שלך. אתה אמור לראות משהו שנראה כך:

/__/firebase/init.js

if (typeof firebase === 'undefined') throw new Error('hosting/init-error: Firebase SDK not detected. You must include it before /__/firebase/init.js');
firebase.initializeApp({
  "apiKey": "qwertyuiop_asdfghjklzxcvbnm1234568_90",
  "databaseURL": "https://friendlychat-1234.firebaseio.com",
  "storageBucket": "friendlychat-1234.appspot.com",
  "authDomain": "friendlychat-1234.firebaseapp.com",
  "messagingSenderId": "1234567890",
  "projectId": "friendlychat-1234",
  "appId": "1:1234567890:web:123456abcdef"
});

כעת ה- SDK של Firebase אמור להיות מוכן לשימוש מכיוון שהוא מיובא ומאותחל index.html . index.html . כעת אנו מיישמים כניסה למשתמש באמצעות אימות Firebase .

אמת את המשתמשים שלך באמצעות כניסה באמצעות Google

באפליקציה, כאשר משתמש לוחץ על כפתור כניסה באמצעות Google , signIn פונקציית signIn . (כבר הגדרנו את זה עבורך!) עבור קוד קוד זה, אנו רוצים לאשר ל- Firebase להשתמש בגוגל כספקית הזהות. נשתמש בקופץ, אך מספר שיטות אחרות זמינות מ- Firebase.

  1. בספריית web-start , בספריית המשנה public/scripts/ , פתח main.js
  2. מצא את הפונקציה signIn .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Signs-in Friendly Chat.
function signIn() {
  // Sign into Firebase using popup auth & Google as the identity provider.
  var provider = new firebase.auth.GoogleAuthProvider();
  firebase.auth().signInWithPopup(provider);
}

הפונקציה signOut מופעלת כאשר המשתמש לוחץ על כפתור יציאה .

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציה signOut .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Signs-out of Friendly Chat.
function signOut() {
  // Sign out of Firebase.
  firebase.auth().signOut();
}

עקוב אחר מצב האימות

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

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציה initFirebaseAuth .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Initiate Firebase Auth.
function initFirebaseAuth() {
  // Listen to auth state changes.
  firebase.auth().onAuthStateChanged(authStateObserver);
}

הקוד שלמעלה רושם את הפונקציה authStateObserver כמשקיף על מצב האימות. זה יופעל בכל פעם שמצב האימות משתנה (כאשר המשתמש נכנס או נכנס). בשלב זה נעדכן את ממשק המשתמש כדי להציג או להסתיר את כפתור הכניסה, כפתור הכניסה, תמונת הפרופיל של המשתמש המחובר וכו '. כל חלקי ממשק המשתמש הללו כבר יושמו.

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

אנו רוצים להציג את תמונת הפרופיל ושם המשתמש של המשתמש המחובר בסרגל העליון של האפליקציה שלנו. ב- Firebase, נתוני המשתמש הכניסה זמינים תמיד באובייקט firebase.auth().currentUser . מוקדם יותר הגדרנו את פונקציית authStateObserver כאשר המשתמש authStateObserver כך שממשק המשתמש שלנו יתעדכן בהתאם. זה יתקשר ל- getProfilePicUrl ו- getUserName כשהוא מופעל.

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציות getProfilePicUrl ו- getUserName .
  3. החלף את שתי הפונקציות בקוד הבא.

main.js

// Returns the signed-in user's profile pic URL.
function getProfilePicUrl() {
  return firebase.auth().currentUser.photoURL || '/images/profile_placeholder.png';
}

// Returns the signed-in user's display name.
function getUserName() {
  return firebase.auth().currentUser.displayName;
}

אנו מציגים הודעת שגיאה אם ​​המשתמש מנסה לשלוח הודעות כאשר המשתמש אינו מחובר. (אם כי אתה יכול לנסות זאת!) לכן עלינו לזהות אם המשתמש מחובר בפועל.

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציה isUserSignedIn .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!firebase.auth().currentUser;
}

בדוק כניסה לאפליקציה

  1. אם האפליקציה שלך עדיין מוגשת, רענן את האפליקציה בדפדפן. אחרת, הפעל את שירות firebase serve --only hosting רק בשורת הפקודה כדי להתחיל לשרת את האפליקציה מ- http: // localhost: 5000 , ואז פתח אותה בדפדפן שלך.
  2. היכנס לאפליקציה באמצעות כפתור הכניסה וחשבון Google שלך. אם אתה רואה הודעת שגיאה המציינת auth/operation-not-allowed , בדוק כדי לוודא שהפעלת את כניסה של Google כספק אימות במסוף Firebase.
  3. לאחר הכניסה, יש להציג את תמונת הפרופיל שלך ואת שם המשתמש: c7401b3d44d0d78b.png

בחלק זה נכתוב כמה נתונים ל- Cloud Firestore כדי שנוכל לאכלס את ממשק המשתמש של האפליקציה. ניתן לעשות זאת באופן ידני באמצעות קונסולת Firebase , אך אנו נעשה זאת באפליקציה עצמה כדי להדגים כתיבה בסיסית של Cloud Firestore.

מודל נתונים

נתוני Cloud Firestore מפוצלים לאוספים, מסמכים, שדות ואוספי משנה. אנו נאחסן כל הודעה בצ'אט כמסמך באוסף ברמה העליונה הנקראת messages .

688d7bc5fb662b57.png

הוסף הודעות ל- Cloud Firestore

כדי לאחסן את הודעות הצ'ט שנכתבו על ידי משתמשים, נשתמש בענן Firestore .

בסעיף זה תוסיף את הפונקציונליות למשתמשים לכתוב הודעות חדשות למסד הנתונים שלך. משתמש שלחץ על הלחצן שלח יפעיל את קטע הקוד למטה. זה מוסיף אובייקט הודעה עם תוכן שדות ההודעות למופע Cloud Firestore שלך ​​באוסף messages . השיטה add() מוסיפה לאוסף מסמך חדש עם מזהה שנוצר אוטומטית.

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציה saveMessage .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Saves a new message to your Cloud Firestore database.
function saveMessage(messageText) {
  // Add a new message entry to the database.
  return firebase.firestore().collection('messages').add({
    name: getUserName(),
    text: messageText,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).catch(function(error) {
    console.error('Error writing new message to database', error);
  });
}

בדוק שליחת הודעות

  1. אם האפליקציה שלך עדיין מוגשת, רענן את האפליקציה בדפדפן. אחרת, הפעל את שירות firebase serve --only hosting רק בשורת הפקודה כדי להתחיל לשרת את האפליקציה מ- http: // localhost: 5000 , ואז פתח אותה בדפדפן שלך.
  2. לאחר הכניסה, הזן הודעה כגון "היי שם!", ואז לחץ על שלח . זה יכתוב את ההודעה ל- Cloud Firestore. עם זאת, עדיין לא תראה את הנתונים באפליקציית האינטרנט האמיתית שלך מכיוון שעדיין אנו צריכים ליישם את אחזור הנתונים (החלק הבא של קוד הקוד).
  3. אתה יכול לראות את ההודעה החדשה שנוספה במסוף Firebase שלך. פתח את מסוף Firebase שלך. תחת הקטע Build לחץ על מסד נתונים (או לחץ כאן ובחר את הפרויקט שלך) ועליך לראות את אוסף ההודעות עם ההודעה החדשה שלך:

6812efe7da395692.png

סנכרן הודעות

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

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

  1. חזור לקובץ public/scripts/main.js
  2. מצא את loadMessages הפונקציה.
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  var query = firebase.firestore()
                  .collection('messages')
                  .orderBy('timestamp', 'desc')
                  .limit(12);
  
  // Start listening to the query.
  query.onSnapshot(function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                       message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

כדי להאזין להודעות במסד הנתונים, אנו יוצרים שאילתה על אוסף באמצעות פונקציית .collection כדי לציין באיזה אוסף הנתונים שרוצים להאזין נמצא. בקוד לעיל אנו מאזינים לשינויים בתוך אוסף messages , שם מאוחסנות הודעות הצ'אט. אנו מיישמים מגבלה על ידי האזנה רק ל 12 ההודעות האחרונות באמצעות .limit(12) והזמנת ההודעות לפי תאריך באמצעות .orderBy('timestamp', 'desc') כדי לקבל את 12 ההודעות החדשות ביותר.

הפונקציה .onSnapshot לוקחת פרמטר אחד: פונקציית התקשרות חוזרת. פונקציית ההתקשרות מופעלת כאשר יש שינויים במסמכים התואמים לשאילתה. זה יכול להיות אם הודעה נמחקת, משתנה או מתווספת. תוכלו לקרוא עוד על כך בתיעוד של Cloud Firestore .

בדוק הודעות סינכרון

  1. אם האפליקציה שלך עדיין מוגשת, רענן את האפליקציה בדפדפן. אחרת, הפעל את שירות firebase serve --only hosting רק בשורת הפקודה כדי להתחיל לשרת את האפליקציה מ- http: // localhost: 5000 , ואז פתח אותה בדפדפן שלך.
  2. ההודעות שיצרת קודם למסד הנתונים צריכות להיות מוצגות בממשק המשתמש של FriendlyChat (ראה להלן). אתם מוזמנים לכתוב הודעות חדשות; הם צריכים להופיע באופן מיידי.
  3. (אופציונלי) באפשרותך לנסות למחוק ידנית, לשנות או להוסיף הודעות חדשות ישירות בקטע מסד הנתונים של מסוף Firebase; כל שינוי צריך לבוא לידי ביטוי בממשק המשתמש.

מזל טוב! אתה קורא מסמכי Cloud Firestore באפליקציה שלך!

2168dec79b573d07.png

כעת נוסיף תכונה המשתפת תמונות.

בעוד ש Firestore בענן טוב לאחסון נתונים מובנים, אחסון ענן מתאים יותר לאחסון קבצים. אחסון ענן עבור Firebase הוא שירות אחסון קבצים / כתמים, ואנחנו נשתמש בו כדי לאחסן את כל התמונות שמשתמש משתף באמצעות האפליקציה שלנו.

שמור תמונות באחסון ענן

עבור קוד קוד זה, כבר הוספנו עבורך כפתור שמפעיל תיבת דו-שיח לבחירת קבצים. לאחר בחירת קובץ, saveImageMessage הפונקציה saveImageMessage ותוכל לקבל הפניה לקובץ שנבחר. הפונקציה saveImageMessage את הפעולות הבאות:

  1. יוצר הודעת צ'אט "מציין מיקום" בפיד הצ'אט, כך שמשתמשים יראו אנימציה "טוען" בזמן שאנחנו מעלים את התמונה.
  2. מעלה את קובץ התמונה לאחסון ענן לנתיב זה: /<uid>/<messageId>/<file_name>
  3. יוצר כתובת אתר לקריאה ציבורית עבור קובץ התמונה.
  4. מעדכן את הודעת הצ'אט בכתובת האתר של קובץ התמונה שזה עתה הועלה במקום תמונת הטעינה הזמנית.

כעת תוסיף את הפונקציונליות לשליחת תמונה:

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציה saveImageMessage .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
function saveImageMessage(file) {
  // 1 - We add a message with a loading icon that will get updated with the shared image.
  firebase.firestore().collection('messages').add({
    name: getUserName(),
    imageUrl: LOADING_IMAGE_URL,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).then(function(messageRef) {
    // 2 - Upload the image to Cloud Storage.
    var filePath = firebase.auth().currentUser.uid + '/' + messageRef.id + '/' + file.name;
    return firebase.storage().ref(filePath).put(file).then(function(fileSnapshot) {
      // 3 - Generate a public URL for the file.
      return fileSnapshot.ref.getDownloadURL().then((url) => {
        // 4 - Update the chat message placeholder with the image's URL.
        return messageRef.update({
          imageUrl: url,
          storageUri: fileSnapshot.metadata.fullPath
        });
      });
    });
  }).catch(function(error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  });
}

בדוק שליחת תמונות

  1. אם האפליקציה שלך עדיין מוגשת, רענן את האפליקציה בדפדפן. אחרת, הפעל את שירות firebase serve --only hosting רק בשורת הפקודה כדי להתחיל לשרת את האפליקציה מ- http: // localhost: 5000 , ואז פתח אותה בדפדפן שלך.
  2. לאחר הכניסה, לחץ על כפתור העלאת התמונה 13734cb66773e5a3.png ובחר קובץ תמונה באמצעות בורר הקבצים. אם אתם מחפשים תמונה, אתם מוזמנים להשתמש בתמונה היפה הזו של כוס קפה .
  3. הודעה חדשה אמורה להופיע בממשק המשתמש של האפליקציה עם התמונה שבחרת: 3b1284f5144b54f6.png

אם תנסה להוסיף תמונה כשאינך מחובר לחשבונך, תראה הודעת טוסט שאומרת שעליך להיכנס כדי להוסיף תמונות.

כעת נוסיף תמיכה בהתראות בדפדפן. האפליקציה תודיע למשתמשים כאשר הודעות חדשות מתפרסמות בצ'אט. העברת הודעות ענן של Firebase (FCM) היא פתרון להעברת הודעות חוצה פלטפורמות המאפשר לך להעביר באופן מהימן הודעות והודעות ללא עלות.

רשימת היתרים של מזהה השולח GCM

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

  1. מספריית הפעלת web-start בספריה public , פתח את manifest.json .
  2. הוסף את ערך מזהה שולח הדפדפן במאפיין gcm_sender_id בדיוק כפי שמוצג להלן. אל תשנה את הערך ממה שמוצג להלן.

manifest.json

{
  "name": "Friendly Chat",
  "short_name": "Friendly Chat",
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "portrait",
  "gcm_sender_id": "103953800507"
}

הוסף את עובד השירות של FCM

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

  1. firebase-messaging-sw.js web-start בספריה public , צור קובץ חדש בשם firebase-messaging-sw.js .
  2. הוסף את התוכן הבא לקובץ החדש ההוא.

firebase-messaging-sw.js

importScripts('/__/firebase/6.0.4/firebase-app.js');
importScripts('/__/firebase/6.0.4/firebase-messaging.js');
importScripts('/__/firebase/init.js');

firebase.messaging();

עובד השירות פשוט צריך לטעון ולאתחל את ה- SDK של העברת הודעות בענן של Firebase, שידאג להצגת התראות.

השג אסימונים למכשירי FCM

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

כאשר המשתמש נכנס לחשבון, אנו קוראים לפונקציה saveMessagingDeviceToken . שם נקבל את אסימון מכשיר ה- FCM מהדפדפן ונשמור אותו בענן Firestore.

  1. חזור לקובץ public/scripts/main.js
  2. מצא את הפונקציה saveMessagingDeviceToken .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Saves the messaging device token to the datastore.
function saveMessagingDeviceToken() {
  firebase.messaging().getToken().then(function(currentToken) {
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to the datastore.
      firebase.firestore().collection('fcmTokens').doc(currentToken)
          .set({uid: firebase.auth().currentUser.uid});
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  }).catch(function(error){
    console.error('Unable to get messaging token.', error);
  });
}

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

בקש הרשאות להצגת התראות

כאשר המשתמש עדיין לא העניק לאפליקציה שלך הרשאה להציג התראות, לא יינתן לך אסימון מכשיר. במקרה זה אנו קוראים firebase.messaging().requestPermission() , שתציג תיבת דו-שיח בדפדפן המבקשת הרשאה זו ( בדפדפנים הנתמכים ).

8b9d0c66dc36153d.png

  1. חזור לקובץ public/scripts/main.js
  2. מצא את requestNotificationsPermissions הפונקציה requestNotificationsPermissions .
  3. החלף את כל הפונקציה בקוד הבא.

main.js

// Requests permission to show notifications.
function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  firebase.messaging().requestPermission().then(function() {
    // Notification permission granted.
    saveMessagingDeviceToken();
  }).catch(function(error) {
    console.error('Unable to get permission to notify.', error);
  });
}

קבל את אסימון המכשיר שלך

  1. אם האפליקציה שלך עדיין מוגשת, רענן את האפליקציה בדפדפן. אחרת, הפעל את שירות firebase serve --only hosting רק בשורת הפקודה כדי להתחיל לשרת את האפליקציה מ- http: // localhost: 5000 , ואז פתח אותה בדפדפן שלך.
  2. לאחר הכניסה, תופיע תיבת הדו-שיח של הרשאות ההודעות: bd3454e6dbfb6723.png
  3. לחץ על אפשר .
  4. פתח את מסוף JavaScript של הדפדפן שלך. אתה אמור לראות את ההודעה הבאה: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. העתק את אסימון המכשיר שלך. תצטרך את זה לשלב הבא של קוד הקוד.

שלח התראה למכשיר שלך

עכשיו שיש לך אסימון המכשיר שלך, אתה יכול לשלוח התראה.

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

כדי לשלוח התראה, יהיה עליך לשלוח את בקשת ה- HTTP הבאה:

POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=YOUR_SERVER_KEY

{
  "notification": {
    "title": "New chat message!",
    "body": "There is a new message in FriendlyChat",
    "icon": "/images/profile_placeholder.png",
    "click_action": "http://localhost:5000"
  },
  "to":"YOUR_DEVICE_TOKEN"
}
  1. בשורת הפקודה, הפעל את הפקודה cURL הבאה.
curl -H "Content-Type: application/json" \
     -H "Authorization: key=YOUR_SERVER_KEY" \
     -d '{
           "notification": {
             "title": "New chat message!",
             "body": "There is a new message in FriendlyChat",
             "icon": "/images/profile_placeholder.png",
             "click_action": "http://localhost:5000"
           },
           "to": "YOUR_DEVICE_TOKEN"
         }' \
     https://fcm.googleapis.com/fcm/send

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

אם האפליקציה שלך ברקע, הודעה אמורה להופיע בדפדפן שלך, כמו בדוגמה זו:

de79e8638a45864c.png

הצג כללי אבטחה של מסד נתונים

Cloud Firestore משתמש בשפת כללים ספציפית כדי להגדיר זכויות גישה, אבטחה ואימות נתונים.

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

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

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

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

firestore.rules

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

עדכן את כללי האבטחה של מסד הנתונים

ישנן שתי דרכים לערוך את כללי האבטחה של מסד הנתונים, במסוף Firebase או מקובץ כללים מקומי שנפרס באמצעות ה- Firebase CLI.

כדי לעדכן את כללי האבטחה במסוף Firebase:

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

כדי לעדכן את כללי האבטחה מקובץ מקומי:

  1. web-start , פתח את firestore.rules .
  2. החלף את כללי ברירת המחדל שכבר נמצאים בקובץ עם הכללים המוצגים לעיל.
  3. מספריית הפעלת web-start פתח את firebase.json .
  4. הוסף את התכונה firestore.rules המפנה אל firestore.rules , כפי שמוצג להלן. (מאפיין hosting צריך להיות כבר בקובץ.)

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. פרוס את כללי האבטחה באמצעות Firebase CLI על ידי הפעלת הפקודה הבאה:
firebase deploy --only firestore
  1. על שורת הפקודה שלך להציג את התגובה הבאה:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

הצג כללי אבטחה של Cloud Storage

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

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

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

אנו נעדכן את הכללים לביצוע הפעולות הבאות:

  • אפשר לכל משתמש לכתוב רק לתיקיות הספציפיות שלו
  • אפשר לכל אחד לקרוא מאחסון ענן
  • ודא שהקבצים שהועלו הם תמונות
  • הגבל את גודל התמונות שניתן להעלות למקסימום 5 מגהבייט

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

storage.rules

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

עדכן את כללי האבטחה של אחסון ענן

ישנן שתי דרכים לערוך את כללי אבטחת האחסון שלך: במסוף Firebase או מקובץ כללים מקומי שנפרס באמצעות ה- CLI של Firebase.

כדי לעדכן את כללי האבטחה במסוף Firebase:

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

כדי לעדכן את כללי האבטחה מקובץ מקומי:

  1. מספריית הפעלת web-start פתח את storage.rules .
  2. החלף את כללי ברירת המחדל שכבר נמצאים בקובץ עם הכללים המוצגים לעיל.
  3. firebase.json web-start פתח את firebase.json .
  4. הוסף את המאפיין storage.rules המפנה לקובץ storage.rules , כמוצג להלן. (מאפיין hosting database צריך להיות כבר בקובץ.)

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // Add this!
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. פרוס את כללי האבטחה באמצעות Firebase CLI על ידי הפעלת הפקודה הבאה:
firebase deploy --only storage
  1. על שורת הפקודה שלך להציג את התגובה הבאה:
=== Deploying to 'friendlychat-1234'...

i  deploying storage
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

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

ישנן דרכים שונות להשתלב ב- SDK של ניטור ביצועי Firebase. במפתח קוד זה הפעלנו ניטור ביצועים מכתובות אתרים לאירוח. עיין בתיעוד כדי לראות שיטות אחרות להפעלת ה- SDK.

עקבות אוטומטיות

מכיוון init.js firebase-performance.js ו- init.js בשלב מוקדם יותר של קוד הקודי, עלינו רק להוסיף שורה אחת שתגיד לניטור ביצועים לאסוף באופן אוטומטי מדדי טעינת עמודים ובקשות רשת כאשר משתמשים מבקרים באתר הפרוס שלך!

  1. ב- public/scripts/main.js , הוסף את השורה הבאה מתחת ל- TODO הקיים כדי לאתחל את ניטור הביצועים.

main.js

// TODO: Enable Firebase Performance Monitoring.
firebase.performance();

מדוד עיכוב קלט ראשון (אופציונלי)

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

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

אם תרצה למדוד את עיכוב הקלט הראשון, יהיה עליך לכלול את הקוד הבא ישירות.

  1. פתח את public/index.html .
  2. בטל את הערת תג script בשורה הבאה.

index.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

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

צפו בנתוני ביצועים

מכיוון שעדיין לא פרסת את האתר שלך (תפרוס אותו בשלב הבא), הנה צילום מסך המציג את המדדים לגבי ביצועי טעינת הדפים שתראה במסוף Firebase תוך 30 דקות ממשתמשים המקיימים אינטראקציה עם האתר הפרוס שלך. :

29389131150f33d7.png

כאשר אתה משלב את SDK לניטור ביצועים באפליקציה שלך, אינך צריך לכתוב שום קוד אחר לפני שהאפליקציה שלך תתחיל לנטר אוטומטית כמה היבטים קריטיים של הביצועים. עבור יישומי אינטרנט, ה- SDK רושם היבטים כמו צבע מרוצה ראשון, יכולת של משתמשים לתקשר עם האפליקציה שלך ועוד.

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

Firebase מציע שירות אירוח לשרת את הנכסים ואפליקציות האינטרנט שלך. באפשרותך לפרוס את הקבצים שלך לאירוח Firebase באמצעות ה- CLI של Firebase. לפני הפריסה, עליך לציין בקובץ firebase.json אילו קבצים מקומיים יש לפרוס. עבור קוד קוד זה, כבר עשינו זאת עבורך מכיוון שצעד זה נדרש לשרת את הקבצים שלנו במהלך קוד קוד זה. הגדרות האירוח מוגדרות תחת מאפיין hosting :

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

הגדרות אלה מספרות ל- CLI שאנו רוצים לפרוס את כל הקבצים בספריה ./public ( "public": "./public" ).

  1. ודא ששורת הפקודה שלך ניגשת לספריית web-start המקומית של האפליקציה שלך.
  2. Deploy your files to your Firebase project by running the following command:
firebase deploy --except functions
  1. The console should display the following:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. Visit your web app that's now fully hosted using Firebase Hosting at two of your very own Firebase subdomains:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app .

Alternatively, you can run firebase open hosting:site in the command line.

Visit the documentation to learn more about how Firebase Hosting works .

Go to your project's Firebase console Hosting section to view useful hosting information and tools, including the history of your deploys, the functionality to roll back to previous versions of your app, and the workflow to set up a custom domain.

You've used Firebase to build a real-time chat web application!

What we've covered

  • Firebase Authentication
  • Cloud Firestore
  • Firebase SDK for Cloud Storage
  • Firebase Cloud Messaging
  • Firebase Performance Monitoring
  • Firebase Hosting

הצעדים הבאים

Learn more