Firebase 網絡代碼實驗室

一、概述

在此 Codelab 中,您將學習如何使用Firebase通過使用 Firebase 產品和服務實現和部署聊天客戶端來輕鬆創建 Web 應用程序。

3b1284f5144b54f6.png

你會學到什麼

  • 使用 Cloud Firestore 和 Cloud Storage for Firebase 同步數據。
  • 使用 Firebase 身份驗證對您的用戶進行身份驗證。
  • 在 Firebase 託管上部署您的網絡應用。
  • 使用 Firebase Cloud Messaging 發送通知。
  • 收集您的 Web 應用程序的性能數據。

你需要什麼

  • 您選擇的 IDE/文本編輯器,例如WebStormAtomSublimeVS Code
  • 包管理器npm ,通常與Node.js一起提供
  • 終端/控制台
  • 您選擇的瀏覽器,例如 Chrome
  • codelab的示例代碼(代碼獲取方法見codelab下一步)

2.獲取示例代碼

從命令行克隆 codelab 的GitHub 存儲庫

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

或者,如果您沒有安裝 git,您可以將存儲庫下載為 ZIP 文件

導入入門應用

使用您的 IDE,從克隆的存儲庫中打開或導入 📁 web-start目錄。這個 📁 web-start目錄包含 codelab 的起始代碼,它將是一個功能齊全的聊天網絡應用程序。

3. 創建並設置 Firebase 項目

創建一個 Firebase 項目

  1. 登錄Firebase
  2. 在 Firebase 控制台中,單擊Add Project ,然後將您的 Firebase 項目命名為FriendlyChat 。記住您的 Firebase 項目的項目 ID。
  3. 取消選中為此項目啟用 Google Analytics
  4. 單擊創建項目

我們要構建的應用程序使用可用於 Web 應用程序的 Firebase 產品:

  • Firebase 身份驗證可讓您的用戶輕鬆登錄您的應用。
  • Cloud Firestore將結構化數據保存在雲端,並在數據更改時獲得即時通知。
  • Cloud Storage for Firebase將文件保存在雲端。
  • Firebase 託管來託管和服務您的資產。
  • Firebase Cloud Messaging發送推送通知並顯示瀏覽器彈出通知。
  • Firebase 性能監控,用於為您的應用收集用戶性能數據。

其中一些產品需要特殊配置或需要使用 Firebase 控制台啟用。

將 Firebase 網絡應用添加到項目中

  1. 點擊網頁圖標58d6543a156e56f9.png創建一個新的 Firebase 網絡應用。
  2. 使用暱稱Friendly Chat註冊該應用,然後選中Also setup Firebase Hosting for this app旁邊的框。點擊註冊應用
  3. 在下一步中,您將看到一個配置對象。僅將 JS 對象(不是周圍的 HTML)複製到firebase-config.js

註冊網頁應用截圖

為 Firebase 身份驗證啟用 Google 登錄

為了允許用戶使用他們的 Google 帳戶登錄網絡應用程序,我們將使用Google登錄方法。

您需要啟用Google登錄:

  1. 在 Firebase 控制台中,找到左側面板中的Build部分。
  2. 點擊Authentication ,然後點擊Sign-in method選項卡(或點擊此處直接前往)。
  3. 啟用Google登錄提供商,然後點擊保存
  4. 將應用程序的公開名稱設置為Friendly Chat ,然後從下拉菜單中選擇項目支持電子郵件
  5. Google Cloud Console中配置您的 OAuth 同意屏幕並添加徽標:

d89fb3873b5d36ae.png

啟用 Cloud Firestore

該網絡應用使用Cloud Firestore來保存聊天消息並接收新的聊天消息。

您需要啟用 Cloud Firestore:

  1. 在 Firebase 控制台的Build部分,點擊Firestore Database
  2. 單擊 Cloud Firestore 窗格中的創建數據庫

729991a081e7cd5.png

  1. 選擇Start in test mode選項,然後在閱讀有關安全規則的免責聲明後單擊Next

測試模式確保我們在開發過程中可以自由地寫入數據庫。稍後我們將在此 Codelab 中使我們的數據庫更加安全。

77e4986cbeaf9dee.png

  1. 設置存儲 Cloud Firestore 數據的位置。您可以將其保留為默認值或選擇您附近的區域。單擊完成以配置 Firestore。

9f2bb0d4e7ca49c7.png

啟用雲存儲

該網絡應用使用 Cloud Storage for Firebase 來存儲、上傳和共享圖片。

您需要啟用雲存儲:

  1. 在 Firebase 控制台的Build部分,點擊Storage
  2. 如果沒有“開始”按鈕,則表示雲存儲已啟用,您無需執行以下步驟。
  3. 單擊開始
  4. 閱讀有關 Firebase 項目安全規則的免責聲明,然後點擊Next

使用默認安全規則,任何經過身份驗證的用戶都可以向 Cloud Storage 寫入任何內容。我們稍後將在此 Codelab 中使我們的存儲更加安全。

62f1afdcd1260127.png

  1. 使用您為 Cloud Firestore 數據庫選擇的同一區域預先選擇了 Cloud Storage 位置。單擊完成以完成設置。

1d7f49ebaddb32fc.png

4.安裝Firebase命令行界面

Firebase 命令行界面 (CLI) 允許您使用 Firebase 託管在本地為您的 Web 應用程序提供服務,以及將您的 Web 應用程序部署到您的 Firebase 項目。

  1. 通過運行以下 npm 命令安裝 CLI:
npm -g install firebase-tools
  1. 通過運行以下命令驗證 CLI 是否已正確安裝:
firebase --version

確保 Firebase CLI 的版本是 v4.1.0 或更高版本。

  1. 通過運行以下命令授權 Firebase CLI:
firebase login

我們已設置 Web 應用模板,以便從應用的本地目錄(您之前在代碼實驗室中克隆的存儲庫)中提取應用的 Firebase 託管配置。但要提取配置,我們需要將您的應用與您的 Firebase 項目相關聯。

  1. 確保您的命令行正在訪問您應用的本地web-start目錄。
  2. 通過運行以下命令將您的應用與 Firebase 項目相關聯:
firebase use --add
  1. 出現提示時,選擇您的Project ID ,然後為您的 Firebase 項目指定一個別名。

如果您有多個環境(生產、登台等),則別名很有用。但是,對於這個 codelab,我們只使用default的別名。

  1. 按照命令行上的其餘說明進行操作。

5.在本地運行starter app

現在您已經導入並配置了您的項目,您已經準備好第一次運行 Web 應用程序了。

  1. web-start目錄的控制台中,運行以下 Firebase CLI 命令:
firebase serve --only hosting
  1. 您的命令行應顯示以下響應:
✔  hosting: Local server: http://localhost:5000

我們正在使用Firebase 託管模擬器在本地為我們的應用提供服務。 Web 應用程序現在應該可以從http://localhost:5000獲得。提供位於public子目錄下的所有文件。

  1. 使用您的瀏覽器,在http://localhost:5000打開您的應用程序。

您應該會看到您的 FriendlyChat 應用程序的 UI,它(還沒有!)運行:

4c23f9475228cef4.png

該應用程序現在無法執行任何操作,但在您的幫助下,它很快就會實現!到目前為止,我們只為您佈置了 UI。

現在讓我們建立一個實時聊天!

6. 導入並配置 Firebase

導入 Firebase SDK

我們需要將 Firebase SDK 導入到應用中。如我們的文檔中所述,有多種方法可以做到這一點。例如,您可以從我們的 CDN 導入庫。或者,您可以使用 npm 在本地安裝它,如果您使用的是 Browserify,則將其打包到您的應用程序中。

我們將從 npm 獲取 Firebase SDK 並使用Webpack來捆綁我們的代碼。我們這樣做是為了讓 Webpack 可以刪除任何不必要的代碼,使我們的 JS 包大小保持較小,以確保我們的應用程序盡快加載。對於這個 codelab,我們已經創建了一個web-start/package.json文件,其中包含 Firebase SDK 作為依賴項,並在web-start/src/index.js的頂部導入了所需的函數。

包.json

"dependencies": {
  "firebase": "^9.0.0"
}

index.js

import { initializeApp } from 'firebase/app';
import {
  getAuth,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup,
  signOut,
} from 'firebase/auth';
import {
  getFirestore,
  collection,
  addDoc,
  query,
  orderBy,
  limit,
  onSnapshot,
  setDoc,
  updateDoc,
  doc,
  serverTimestamp,
} from 'firebase/firestore';
import {
  getStorage,
  ref,
  uploadBytesResumable,
  getDownloadURL,
} from 'firebase/storage';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getPerformance } from 'firebase/performance';

在此 Codelab 中,我們將使用 Firebase 身份驗證、Cloud Firestore、Cloud Storage、Cloud Messaging 和 Performance Monitoring,因此我們將導入它們的所有庫。在您未來的應用中,請確保您只導入您需要的 Firebase 部分,以縮短應用的加載時間。

安裝 Firebase SDK 並開始你的 Webpack 構建

我們需要運行一些命令來構建我們的應用程序。

  1. 打開一個新的終端窗口
  2. 確保您位於web-start目錄中
  3. 運行npm install以下載 Firebase SDK
  4. 運行npm run start啟動 Webpack。 Webpack 現在將為 codelab 的其餘部分不斷重建我們的源代碼。

配置 Firebase

我們還需要配置 Firebase SDK 以告訴它我們正在使用哪個 Firebase 項目。

  1. 轉到Firebase 控制台中的項目設置
  2. 在“您的應用”卡片中,選擇您需要配置對象的應用的暱稱。
  3. 從 Firebase SDK 片段窗格中選擇“配置”。
  4. 複製配置對象片段,然後將其添加到web-start/src/firebase-config.js

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

現在,轉到web-start/src/index.js的底部並初始化 Firebase:

index.js

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

7.設置用戶登錄

Firebase SDK 現在應該可以使用了,因為它已在index.js中導入和初始化。我們現在將使用Firebase Authentication實現用戶登錄。

使用 Google 登錄對您的用戶進行身份驗證

在應用程序中,當用戶單擊“使用 Google 登錄”按鈕時,會觸發signIn功能。 (我們已經為您設置好了!)對於這個 Codelab,我們想要授權 Firebase 使用 Google 作為身份提供者。我們將使用彈出窗口,但 Firebase 提供了其他幾種方法

  1. web-start目錄的子目錄src/中,打開index.js
  2. 找到函數signIn
  3. 用以下代碼替換整個函數。

index.js

// Signs-in Friendly Chat.
async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider);
}

當用戶單擊退出按鈕時,將觸發signOut功能。

  1. 回到文件src/index.js
  2. 找到函數signOutUser
  3. 用以下代碼替換整個函數。

index.js

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

跟踪身份驗證狀態

為了相應地更新我們的 UI,我們需要一種方法來檢查用戶是登錄還是退出。使用 Firebase 身份驗證,您可以在身份驗證狀態上註冊一個觀察者,每次身份驗證狀態更改時都會觸發該觀察者。

  1. 回到文件src/index.js
  2. 找到函數initFirebaseAuth
  3. 用以下代碼替換整個函數。

index.js

// Initialize firebase auth
function initFirebaseAuth() {
  // Listen to auth state changes.
  onAuthStateChanged(getAuth(), authStateObserver);
}

上面的代碼將函數authStateObserver註冊為身份驗證狀態觀察者。每次身份驗證狀態更改時(用戶登錄或註銷時)都會觸發。此時,我們將更新 UI 以顯示或隱藏登錄按鈕、退出按鈕、登錄用戶的個人資料圖片等。所有這些 UI 部分都已經實現。

顯示登錄用戶的信息

我們希望在應用的頂部欄中顯示登錄用戶的頭像和用戶名。在 Firebase 中,登錄用戶的數據始終在currentUser對像中可用。之前,我們設置了authStateObserver函數以在用戶登錄時觸發,以便我們的 UI 相應更新。它會在觸發時調用getProfilePicUrlgetUserName

  1. 回到文件src/index.js
  2. 找到函數getProfilePicUrlgetUserName
  3. 用以下代碼替換這兩個函數。

index.js

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

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

如果用戶在未登錄時嘗試發送消息,我們會顯示錯誤消息。(不過,您可以嘗試一下!)因此,我們需要檢測用戶是否實際登錄。

  1. 回到文件src/index.js
  2. 找到函數isUserSignedIn
  3. 用以下代碼替換整個函數。

index.js

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

測試登錄應用

  1. 如果您的應用仍在提供服務,請在瀏覽器中刷新您的應用。否則,在命令行上運行firebase serve --only hosting以從http://localhost:5000開始為應用程序提供服務,然後在瀏覽器中打開它。
  2. 使用登錄按鈕和您的 Google 帳戶登錄應用程序。如果您看到說明auth/operation-not-allowed的錯誤消息,請檢查以確保您在 Firebase 控制台中啟用了 Google 登錄作為身份驗證提供程序。
  3. 登錄後,應顯示您的個人資料圖片和用戶名: c7401b3d44d0d78b.png

8. 向 Cloud Firestore 寫入消息

在本節中,我們將向 Cloud Firestore 寫入一些數據,以便我們可以填充應用的 UI。這可以使用Firebase 控制台手動完成,但我們將在應用程序本身中執行此操作以演示基本的 Cloud Firestore 編寫。

數據模型

Cloud Firestore 數據分為集合、文檔、字段和子集合。我們會將聊天的每條消息作為文檔存儲在名為messages的頂級集合中。

688d7bc5fb662b57.png

向 Cloud Firestore 添加消息

要存儲用戶編寫的聊天消息,我們將使用Cloud Firestore

在本節中,您將為用戶添加將新消息寫入數據庫的功能。用戶單擊“發送”按鈕將觸發下面的代碼片段。它將包含消息字段內容的消息對象添加到messages集合中的 Cloud Firestore 實例。 add()方法將具有自動生成的 ID 的新文檔添加到集合中。

  1. 回到文件src/index.js
  2. 找到函數saveMessage
  3. 用以下代碼替換整個函數。

index.js

// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
  // Add a new message entry to the Firebase database.
  try {
    await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      text: messageText,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });
  }
  catch(error) {
    console.error('Error writing new message to Firebase Database', error);
  }
}

測試發送消息

  1. 如果您的應用仍在提供服務,請在瀏覽器中刷新您的應用。否則,在命令行上運行firebase serve --only hosting以從http://localhost:5000開始為應用程序提供服務,然後在瀏覽器中打開它。
  2. 登錄後,輸入諸如“Hey there!”之類的消息,然後單擊“發送”。這會將消息寫入 Cloud Firestore。但是,您還不會在實際的 Web 應用程序中看到數據,因為我們仍然需要實現檢索數據(代碼實驗室的下一部分)。
  3. 您可以在 Firebase 控制台中看到新添加的消息。打開您的 Firebase 控制台。在Build部分下單擊Firestore Database (或單擊此處並選擇您的項目),您應該會看到帶有新添加消息的消息集合:

6812efe7da395692.png

9.閱讀信息

同步消息

要在應用程序中讀取消息,我們需要添加在數據更改時觸發的偵聽器,然後創建一個顯示新消息的 UI 元素。

我們將添加用於偵聽來自應用程序的新添加消息的代碼。在此代碼中,我們將註冊偵聽器以偵聽對數據所做的更改。我們將只顯示聊天的最後 12 條消息,以避免在加載時顯示很長的歷史記錄。

  1. 回到文件src/index.js
  2. 找到函數loadMessages
  3. 用以下代碼替換整個函數。

index.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.
  const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
  
  // Start listening to the query.
  onSnapshot(recentMessagesQuery, 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中的更改集合,這是存儲聊天消息的地方。我們還通過使用.limit(12)僅收聽最後 12 條消息並使用orderBy('timestamp', 'desc')按日期對消息排序以獲得 12 條最新消息來應用限制。

onSnapshot函數將查詢作為其第一個參數,將一個回調函數作為其第二個參數。當與查詢匹配的文檔發生任何更改時,將觸發回調函數。這可能是消息被刪除、修改或添加。您可以在Cloud Firestore 文檔中閱讀更多相關信息。

測試同步消息

  1. 如果您的應用仍在提供服務,請在瀏覽器中刷新您的應用。否則,在命令行上運行firebase serve --only hosting以從http://localhost:5000開始為應用程序提供服務,然後在瀏覽器中打開它。
  2. 您之前在數據庫中創建的消息應顯示在 FriendlyChat UI 中(見下文)。隨意寫新消息;它們應該立即出現。
  3. (可選)您可以嘗試直接在 Firebase 控制台的數據庫部分手動刪除、修改或添加新消息;任何更改都應反映在 UI 中。

恭喜!您正在應用中閱讀 Cloud Firestore 文檔!

2168dec79b573d07.png

10. 發送圖片

我們現在將添加一個共享圖像的功能。

雖然 Cloud Firestore 適合存儲結構化數據,但 Cloud Storage 更適合存儲文件。 Cloud Storage for Firebase是一種文件/blob 存儲服務,我們將使用它來存儲用戶使用我們的應用共享的任何圖像。

將圖像保存到雲存儲

對於此 Codelab,我們已經為您添加了一個觸發文件選擇器對話框的按鈕。選擇文件後,會調用saveImageMessage函數,您可以獲取對所選文件的引用。 saveImageMessage函數完成以下任務:

  1. 在聊天提要中創建“佔位符”聊天消息,以便用戶在我們上傳圖像時看到“加載”動畫。
  2. 將圖像文件上傳到 Cloud Storage 到以下路徑: /<uid>/<messageId>/<file_name>
  3. 為圖像文件生成一個公開可讀的 URL。
  4. 使用新上傳的圖像文件的 URL 更新聊天消息,而不是臨時加載圖像。

現在您將添加發送圖像的功能:

  1. 回到文件src/index.js
  2. 找到函數saveImageMessage
  3. 用以下代碼替換整個函數。

index.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
async function saveImageMessage(file) {
  try {
    // 1 - We add a message with a loading icon that will get updated with the shared image.
    const messageRef = await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      imageUrl: LOADING_IMAGE_URL,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${getAuth().currentUser.uid}/${messageRef.id}/${file.name}`;
    const newImageRef = ref(getStorage(), filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    });
  } catch (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. 應用程序的 UI 中應該會出現一條新消息,其中包含您選擇的圖像: 3b1284f5144b54f6.png

如果您在未登錄的情況下嘗試添加圖像,您應該會看到一條 Toast 通知,告訴您必須登錄才能添加圖像。

11. 顯示通知

我們現在將添加對瀏覽器通知的支持。該應用程序將在聊天中發布新消息時通知用戶。 Firebase 雲消息傳遞(FCM) 是一種跨平台消息傳遞解決方案,可讓您免費可靠地傳遞消息和通知。

添加 FCM 服務工作者

Web 應用程序需要一個服務工作者來接收和顯示 Web 通知。

  1. web-start目錄的src目錄中,打開firebase-messaging-sw.js
  2. 將以下內容添加到該文件。

firebase-messaging-sw.js

// Import and configure the Firebase SDK
import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { getFirebaseConfig } from './firebase-config';

const firebaseApp = initializeApp(getFirebaseConfig());
getMessaging(firebaseApp);
console.info('Firebase messaging service worker is set up');

Service Worker 只需要加載和初始化 Firebase Cloud Messaging SDK,它將負責顯示通知。

獲取 FCM 設備令牌

在設備或瀏覽器上啟用通知後,您將獲得一個設備令牌。這個設備令牌是我們用來向特定設備或特定瀏覽器發送通知的。

當用戶登錄時,我們調用saveMessagingDeviceToken函數。我們將從瀏覽器獲取FCM 設備令牌並將其保存到 Cloud Firestore。

  1. 回到文件src/index.js
  2. 找到函數saveMessagingDeviceToken
  3. 用以下代碼替換整個函數。

index.js

// Saves the messaging device token to Cloud Firestore.
async function saveMessagingDeviceToken() {
  try {
    const currentToken = await getToken(getMessaging());
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to Cloud Firestore.
      const tokenRef = doc(getFirestore(), 'fcmTokens', currentToken);
      await setDoc(tokenRef, { uid: getAuth().currentUser.uid });

      // This will fire when a message is received while the app is in the foreground.
      // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
      onMessage(getMessaging(), (message) => {
        console.log(
          'New foreground notification from Firebase Messaging!',
          message.notification
        );
      });
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  } catch(error) {
    console.error('Unable to get messaging token.', error);
  };
}

但是,此代碼最初無法正常工作。為了讓您的應用能夠檢索設備令牌,用戶需要授予您的應用顯示通知的權限(codelab 的下一步)。

請求顯示通知的權限

當用戶尚未授予您的應用顯示通知的權限時,您將不會獲得設備令牌。在這種情況下,我們調用firebase.messaging().requestPermission()方法,該方法將顯示一個瀏覽器對話框,請求此權限(在支持的瀏覽器中)。

8b9d0c66dc36153d.png

  1. 回到文件src/index.js
  2. 找到函數requestNotificationsPermissions
  3. 用以下代碼替換整個函數。

index.js

// Requests permissions to show notifications.
async function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  const permission = await Notification.requestPermission();
  
  if (permission === 'granted') {
    console.log('Notification permission granted.');
    // Notification permission granted.
    await saveMessagingDeviceToken();
  } else {
    console.log('Unable to get permission to notify.');
  }
}

獲取您的設備令牌

  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 控制台的 Cloud Messaging 選項卡
  2. 點擊“新通知”
  3. 輸入通知標題和通知文本。
  4. 在屏幕右側,點擊“發送測試消息”
  5. 輸入您從瀏覽器的 JavaScript 控制台複製的設備令牌,然後單擊加號 ("+")
  6. 點擊“測試”

如果您的應用程序位於前台,您將在 JavaScript 控制台中看到通知。

如果您的應用程序在後台,則瀏覽器中應該會顯示一條通知,如下例所示:

de79e8638a45864c.png

12. Cloud Firestore 安全規則

查看數據庫安全規則

Cloud Firestore 使用特定的規則語言來定義訪問權限、安全性和數據驗證。

在本 Codelab 開始時設置 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.rulesfirestore.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

13、雲存儲安全規則

查看 Cloud Storage 安全規則

Cloud Storage for Firebase 使用特定的規則語言來定義訪問權限、安全性和數據驗證。

在本 Codelab 開始時設置 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;
    }
  }
}

我們將更新規則以執行以下操作:

  • 允許每個用戶只寫入他們自己的特定文件夾
  • 允許任何人從 Cloud Storage 讀取
  • 確保上傳的文件是圖片
  • 將可上傳的圖片大小限制為最大 5 MB

這可以使用以下規則來實現:

存儲規則

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

更新 Cloud Storage 安全規則

有兩種方法可以編輯您的存儲安全規則:在 Firebase 控制台中或從使用 Firebase CLI 部署的本地規則文件中。

要在 Firebase 控制台中更新安全規則:

  1. 從左側面板轉到存儲部分,然後單擊規則選項卡。
  2. 將控制台中已有的默認規則替換為上面顯示的規則。
  3. 單擊發布

從本地文件更新安全規則:

  1. web-start目錄,打開storage.rules
  2. 將文件中已有的默認規則替換為上面顯示的規則。
  3. web-start目錄,打開firebase.json
  4. 添加指向storage.rules文件的storage.rules屬性,如下所示。 ( hostingdatabase屬性應該已經在文件中。)

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

14.收集性能數據

您可以使用性能監控 SDK 從您的應用收集真實的性能數據,然後在 Firebase 控制台中查看和分析這些數據。性能監控可幫助您了解可以在何處以及何時改進應用程序的性能,以便您可以使用該信息來解決性能問題。

有多種方法可以與 Firebase 性能監控 JavaScript SDK 集成。在此 Codelab 中,我們啟用了Hosting URLs的性能監控。請參閱文檔以查看啟用 SDK 的其他方法。

自動追踪

由於我們已經在web-start/src/index.js的頂部導入getPerformance ,我們只需要添加一行來告訴性能監控在用戶訪問您部署的站點時自動為您收集頁面加載和網絡請求指標!

  1. web-start/src/index.js中,在現有TODO下方添加以下行以初始化性能監控。

index.js

// TODO: Enable Firebase Performance Monitoring.
getPerformance();

測量第一個輸入延遲(可選)

首次輸入延遲很有用,因為瀏覽器對用戶交互的響應會為您的用戶提供有關應用響應能力的第一印象。

首次輸入延遲從用戶第一次與頁面上的元素交互時開始,例如單擊按鈕或超鏈接。它在瀏覽器能夠響應輸入後立即停止,這意味著瀏覽器沒有忙於加載或解析您的頁面內容。

如果您想測量第一次輸入延遲,則需要直接包含以下代碼。

  1. 打開public/index.html
  2. 取消註釋以下行中的script標記。

索引.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>

要閱讀有關第一個輸入延遲 polyfill 的更多信息,請查看文檔

查看性能數據

由於您尚未部署您的網站(您將在下一步中部署它),下面的屏幕截圖顯示了有關頁面加載性能的指標,您將在用戶與您部署的網站交互的 30 分鐘內在 Firebase 控制台中看到這些指標:

29389131150f33d7.png

當您將性能監控 SDK 集成到您的應用程序中時,您無需編寫任何其他代碼,您的應用程序就會開始自動監控性能的幾個關鍵方面。對於 Web 應用程序,SDK 會記錄諸如首次內容繪製、用戶與您的應用程序交互的能力等方面。

您還可以設置自定義跟踪、指標和屬性來衡量應用程序的特定方面。訪問文檔以了解有關自定義跟踪和度量以及自定義屬性的更多信息。

15. 使用 Firebase 託管部署您的應用

Firebase 提供託管服務來為您的資產和網絡應用提供服務。您可以使用 Firebase CLI 將文件部署到 Firebase 託管。在部署之前,您需要在firebase.json文件中指定應該部署哪些本地文件。對於此 Codelab,我們已經為您完成了此操作,因為在此 Codelab 期間提供我們的文件需要此步驟。託管設置在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. 通過運行以下命令將文件部署到 Firebase 項目:
firebase deploy --except functions
  1. 控制台應顯示以下內容:
=== 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. 在您自己的兩個 Firebase 子域中使用 Firebase 託管訪問您現在完全託管在全球 CDN 上的網絡應用:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

或者,您可以在命令行中運行firebase open hosting:site

請訪問文檔以詳細了解Firebase 託管的工作原理

轉到您項目的 Firebase 控制台託管部分以查看有用的託管信息和工具,包括您的部署歷史、回滾到應用程序以前版本的功能以及設置自定義域的工作流程。

16. 恭喜!

您已經使用 Firebase 構建了一個實時聊天 Web 應用程序!

我們涵蓋的內容

  • Firebase 身份驗證
  • 雲防火牆
  • 用於雲存儲的 Firebase SDK
  • Firebase 雲消息傳遞
  • Firebase 性能監控
  • Firebase 託管

下一步

Learn more