AngularFire 網頁程式碼研究室

1. 總覽

在這個程式碼研究室中,您將瞭解如何使用 Firebase 產品與服務實作及部署即時通訊用戶端,藉此使用 AngularFire 建立網頁應用程式。

可讓使用者討論 Firebase 的即時通訊應用程式

課程內容

  • 使用 Angular 和 Firebase 建構網頁應用程式。
  • 使用 Cloud Firestore 和 Cloud Storage for Firebase 同步處理資料。
  • 透過 Firebase 驗證功能驗證使用者。
  • 在 Firebase 應用程式託管服務部署網頁應用程式。
  • 使用 Firebase 雲端通訊傳送通知。
  • 收集網頁應用程式的成效資料。

事前準備

  • GitHub 帳戶
  • 能將 Firebase 專案升級至 Blaze 定價方案
  • 您選擇的 IDE/文字編輯器,例如 WebStormSublimeVS Code
  • 套件管理員 npm,通常會隨附 Node.js
  • 終端機/控制台
  • 您選擇的瀏覽器,例如 Chrome
  • 程式碼研究室的程式碼範例 (請參閱程式碼研究室的下一個步驟,瞭解如何取得程式碼)。

2. 取得範例程式碼

建立 GitHub 存放區

您可以在 https://github.com/firebase/codelab-相容 chat-web 找到程式碼研究室的來源。這個存放區含有適用於多個平台的範例專案。不過,本程式碼研究室只會使用 angularfire-start 目錄。

angularfire-start 資料夾複製到自己的存放區:

  1. 使用終端機在電腦上建立新資料夾,然後變更為新目錄:
    mkdir codelab-friendlyeats-web
    
    cd codelab-friendlyeats-web
    
  2. 使用 giget npm 套件只擷取 angularfire-start 資料夾:
    npx giget@latest gh:firebase/codelab-friendlychat-web/angularfire-start#master . --install
    
  3. 使用 Git 追蹤本機變更:
    git init
    
    git add .
    
    git commit -m "codelab starting point"
    
    git branch -M main
    
  4. 建立新的 GitHub 存放區:https://github.com/new。視需要命名。
    1. GitHub 會為您提供新的存放區網址,看起來像是 https://github.com/[user-name]/[repository-name].gitgit@github.com:[user-name]/[repository-name].git。請複製這個網址。
  5. 將本機變更推送至新的 GitHub 存放區。執行下列指令,將 your-repository-url 預留位置替換成您的存放區網址。
    git remote add origin your-repository-url
    
    git push -u origin main
    
  6. 現在 GitHub 存放區中應該會顯示範例程式碼。

3. 建立及設定 Firebase 專案

建立 Firebase 專案

  1. 登入 Firebase 控制台
  2. 在 Firebase 控制台中,按一下「新增專案」,然後將 Firebase 專案命名為 friendlyChat。記下 Firebase 專案的專案 ID。
  3. 取消勾選「為這項專案啟用 Google Analytics (分析)」
  4. 按一下 [Create Project] (建立專案)

您要建構的應用程式所使用的 Firebase 產品適用於網頁應用程式:

  • Firebase 驗證功能,方便使用者登入您的應用程式。
  • Cloud Firestore:可將結構化資料儲存至雲端,並在資料變更時立即收到通知。
  • Cloud Storage for Firebase:可將檔案儲存在雲端。
  • Firebase 應用程式代管,用於建構、託管及提供應用程式。
  • Firebase 雲端通訊:可傳送推播通知,以及顯示瀏覽器彈出式通知。
  • Firebase 效能監控功能:收集您應用程式的使用者效能資料。

部分產品需要特殊設定,或透過 Firebase 控制台啟用。

升級 Firebase 定價方案

如要使用 App 託管功能,你的 Firebase 專案必須採用 Blaze 定價方案,也就是會與 Cloud Billing 帳戶建立關聯。

  • Cloud Billing 帳戶需要付款方式 (例如信用卡)。
  • 如果你是第一次使用 Firebase 和 Google Cloud,請確認自己是否符合 $300 美元的抵免額資格,並擁有免費試用 Cloud Billing 帳戶

如要將專案升級至 Blaze 方案,請按照下列步驟操作:

  1. 在 Firebase 控制台中,選擇升級方案
  2. 在對話方塊中選取 Blaze 方案,然後按照畫面上的指示將專案連結至 Cloud Billing 帳戶。
    如需建立 Cloud Billing 帳戶,可能需要回到 Firebase 控制台的升級流程完成升級。

將 Firebase 網頁應用程式新增至專案

  1. 按一下網站圖示 58d6543a156e56f9.png,建立新的 Firebase 網頁應用程式。
  2. 使用暱稱「friendly Chat」註冊應用程式。請不要勾選「一併為這個應用程式設定 Firebase 託管」旁的方塊,然後按一下「註冊應用程式」
  3. 下一個步驟中會顯示設定物件。你暫時不需要。按一下 [Continue to console] (前往主控台)。

註冊網頁應用程式螢幕截圖

設定驗證方法

如要允許使用者以自己的 Google 帳戶登入網頁應用程式,請使用 Google 登入方式。

  1. 在 Firebase 控制台中,前往「驗證」
  2. 按一下「開始」
  3. 在「其他供應商」欄中,依序按一下「Google」>「啟用」。
  4. 在「對專案公開名稱」文字方塊中,輸入好記的名稱,例如 My Next.js app
  5. 從「專案支援電子郵件」下拉式選單中,選取您的電子郵件地址。
  6. 按一下「儲存」

啟用 Cloud Firestore

網頁應用程式會使用 Cloud Firestore 儲存即時通訊訊息並接收新的即時通訊訊息。

您必須啟用 Cloud Firestore:

  1. 在 Firebase 控制台中,前往「Firestore」
  2. 依序點選「建立資料庫」>「下一步」>「以測試模式開始」>「下一步」
    稍後在本程式碼研究室中,您將新增安全性規則,保護資料。請勿在未為資料庫新增安全性規則的情況下,公開發行或公開應用程式。
  3. 使用預設位置或選取您所選擇的位置。
    如果是實際應用程式,建議您選擇離使用者較近的位置。請注意,這個位置之後「無法」變更,而且也會自動成為您預設 Cloud Storage 值區的位置 (下一步)。
  4. 點選「完成」

啟用 Cloud Storage

網頁應用程式使用 Cloud Storage for Firebase 儲存、上傳及分享相片。

您需要啟用 Cloud Storage:

  1. 在 Firebase 控制台中,前往「儲存空間」
  2. 依序點選「開始使用」>「以測試模式開始」>「下一步」
    稍後在本程式碼研究室中,您將新增安全性規則,保護資料。請勿在未為 Storage 值區新增安全性規則的情況下,公開發布或公開應用程式。
  3. 由於您在上一步中設定 Firestore,因此系統應該已選取值區的位置。
  4. 點選「完成」

4. 安裝 Firebase 指令列介面

透過 Firebase 指令列介面 (CLI),您可以使用 Firebase 託管功能在本機提供網頁應用程式,並將網頁應用程式部署至 Firebase 專案。

  1. 執行下列 npm 指令安裝 CLI:
npm -g install firebase-tools@latest
  1. 執行下列指令,確認 CLI 已正確安裝:
firebase --version

請確認 Firebase CLI 版本為 13.9.0 以上版本。

  1. 執行下列指令,授權 Firebase CLI:
firebase login

您已設定網頁應用程式範本,以便從應用程式的本機目錄 (先前在程式碼研究室中複製的存放區) 提取應用程式的設定,以用於 Firebase 託管。不過,如要提取設定,您必須將應用程式與 Firebase 專案建立關聯。

  1. 請確認指令列正在存取應用程式的本機 angularfire-start 目錄。
  2. 執行下列指令,將應用程式與 Firebase 專案建立關聯:
firebase use --add
  1. 系統提示時,請選取您的「專案 ID」,然後為 Firebase 專案設定別名。

別名在有多個環境 (正式環境、測試環境等) 時非常實用。但在本程式碼研究室中,我們直接使用 default 的別名。

  1. 按照指令列中的其餘指示進行。

5. 安裝 AngularFire

執行專案之前,請確認您已設定 Angular CLI 和 AngularFire。

  1. 在控制台中執行下列指令:
npm install -g @angular/cli
  1. 接著,在 angularfire-start 目錄的主控台中執行下列 Angular CLI 指令:
ng add @angular/fire

這會為專案安裝所有必要的依附元件。

  1. 系統提示時,取消勾選包含空格鍵的 ng deploy -- hosting。使用方向鍵和空格鍵選取下列功能:
    • Authentication
    • Firestore
    • Cloud Messaging
    • Cloud Storage
  2. 請按下 enter 鍵,然後按照其餘提示操作。
  3. 建立修訂版本訊息「Install AngularFire」,並推送至 GitHub 存放區。

6. 建立 App Hosting 後端

在本節中,您將設定 App Hosting 後端,以便監控 Git 存放區中的分支版本。

完成本節結束時,您有一個 App Hosting 後端會連結至 GitHub 中的存放區,每當您將新的修訂版本推送至 main 分支版本時,系統就會自動重新建構及推出新版應用程式。

  1. 前往 Firebase 控制台的「App Hosting」頁面:

App Managed Console 的零狀態,以及「開始使用」按鈕

  1. 按一下 [開始使用] 即可啟動後端建立流程。請按照下列方式設定後端:
  2. 按照第一個步驟中的提示,連結您先前建立的 GitHub 存放區。
  3. 進行部署設定:
    1. 將根目錄保留為 /
    2. 將使用中的分支版本設為 main
    3. 啟用自動推出功能
  4. 將後端命名為 friendlychat-codelab
  5. 在「建立或連結 Firebase 網頁應用程式」中,從「選取現有的 Firebase 網頁應用程式」下拉式選單中,選取您先前設定的網頁應用程式。
  6. 按一下「Finish and 部署」。稍後系統會將您導向新頁面,讓您查看新 App Hosting 後端的狀態!
  7. 推出完成後,按一下「網域」下方的免費網域。由於 DNS 傳播,這項作業可能需要幾分鐘的時間才能開始執行。

您已部署初始網頁應用程式!每次您將新修訂版本推送至 GitHub 存放區的 main 分支版本時,就會在 Firebase 控制台中看到新的建構作業和推出作業,而且推出完成後,網站會自動更新。

App Managed Console 的零狀態,以及「開始使用」按鈕

您應該會看到 CompatibilityChat 應用程式的登入畫面,但登入畫面目前無法正常運作。

這個應用程式目前無法執行任何操作,但很快就能提供協助!

接著,我們要建構即時即時通訊應用程式。

7. 匯入及設定 Firebase

設定 Firebase

您需要設定 Firebase SDK,讓 SDK 知道您目前使用的 Firebase 專案為何。

  1. 前往 Firebase 控制台中的專案設定
  2. 在「您的應用程式」資訊卡中,選取您要設定設定物件的應用程式暱稱。
  3. 從 Firebase SDK 程式碼片段窗格中選取 [Config]。

您會發現系統已為您產生環境檔案 /angularfire-start/src/environments/environment.ts

  1. 複製設定物件片段,然後新增至 angularfire-start/src/firebase-config.js

environment.ts

export const environment = {
  firebase: {
    apiKey: "API_KEY",
    authDomain: "PROJECT_ID.firebaseapp.com",
    projectId: "PROJECT_ID",
    storageBucket: "PROJECT_ID.appspot.com",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
  },
};

查看 AngularFire 設定

您在控制台中選取的功能會自動新增至 /angularfire-start/src/app/app.config.ts 檔案中。這項權限可讓應用程式使用 Firebase 的功能。

8. 設定使用者登入

現在可以使用 AngularFire,因為 app.config.ts 已匯入並初始化。現在,您要使用 Firebase 驗證導入使用者登入功能。

新增授權網域

Firebase 驗證功能只允許從一組由由您控管的網域登入。將您的免費應用程式託管網域新增至網域清單:

  1. 前往「App 託管」
  2. 複製後端網域。
  3. 前往「驗證設定」
  4. 選擇「已授權網域」分頁標籤。
  5. 按一下「Add domain」(新增網域),然後貼上 App Hosting 後端網域。

透過 Google 登入機制驗證使用者

在應用程式中,當使用者點選「使用 Google 帳戶登入」按鈕時,就會觸發 login 函式。在本程式碼研究室中,您想授權 Firebase 使用 Google 做為識別資訊提供者。您將使用彈出式視窗,但 Firebase 還提供其他幾種方法

  1. 在子目錄 /src/app/services/ 中,開啟 chat.service.ts
  2. 找出 login 函式。
  3. 將整個函式替換為以下程式碼。

chat.service.ts

// Signs-in Friendly Chat.
login() {
    signInWithPopup(this.auth, this.provider).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        this.router.navigate(['/', 'chat']);
        return credential;
    })
}

使用者按一下「Log out」按鈕時,就會觸發 logout 函式。

  1. 返回 src/app/services/chat.service.ts 檔案。
  2. 找出 logout 函式。
  3. 將整個函式替換為以下程式碼。

chat.service.ts

// Logout of Friendly Chat.
logout() {
    signOut(this.auth).then(() => {
        this.router.navigate(['/', 'login'])
        console.log('signed out');
    }).catch((error) => {
        console.log('sign out error: ' + error);
    })
}

追蹤驗證狀態

如要據此更新使用者介面,您必須檢查使用者是否已登入或登出。AngularFire 提供函式以取得可觀測項目,該函式會在每次驗證狀態變更時更新。雖然目前已採行這項措施,但值得一試。

  1. 返回 src/app/services/chat.service.ts 檔案。
  2. 找出變數指派 user$

chat.service.ts

// observable that is updated when the auth state changes
user$ = user(this.auth);

上述程式碼會呼叫 AngularFire 函式 user,以傳回可觀測的使用者。每當驗證狀態有所變更 (使用者登入或登出時),就會觸發檢索器。SafeChat 中的 Angular 範本元件會使用這個可觀測項目更新 UI,以便進行重新導向、在標頭導覽面板中顯示使用者等等。

測試登入應用程式

  1. 建立修訂版本訊息「Add Google Authentication」,並推送至 GitHub 存放區。
  2. 在 Firebase 控制台中開啟應用程式託管頁面,然後等待新推出作業完成。
  3. 在網頁應用程式中,重新整理頁面,並使用登入按鈕和您的 Google 帳戶登入應用程式。如果系統顯示「auth/operation-not-allowed」錯誤訊息,請確認您已在 Firebase 控制台中啟用 Google 登入做為驗證供應商。
  4. 登入後,你的個人資料相片和使用者名稱應會顯示:angularfire-3.png

9. 將訊息寫入 Cloud Firestore

在本節中,您會在 Cloud Firestore 中寫入一些資料,以便填入應用程式的 UI。您可使用 Firebase 控制台手動完成這項操作,不過您必須在應用程式中執行這項作業,以便示範基本的 Cloud Firestore 寫入作業。

資料模型

Cloud Firestore 資料分為集合、文件、欄位和子集合。將即時通訊訊息的每則訊息儲存為文件,並存放在名為 messages 的頂層集合中。

688d7bc5fb662b57.png

將訊息新增至 Cloud Firestore

如要儲存使用者撰寫的即時通訊訊息,請使用 Cloud Firestore

在本節中,您將新增讓使用者將新訊息寫入您的資料庫的功能。使用者按一下「傳送」按鈕會觸發下列程式碼片段。這會將含有訊息欄位內容的訊息物件新增至 messages 集合中的 Cloud Firestore 執行個體。add() 方法會將內含自動產生的 ID 的新文件新增至集合。

  1. 返回 src/app/services/chat.service.ts 檔案。
  2. 找出 addMessage 函式。
  3. 將整個函式替換為以下程式碼。

chat.service.ts

// Adds a text or image message to Cloud Firestore.
addMessage = async (
  textMessage: string | null,
  imageUrl: string | null,
): Promise<void | DocumentReference<DocumentData>> => {
  // ignore empty messages
  if (!textMessage && !imageUrl) {
    console.log(
      "addMessage was called without a message",
      textMessage,
      imageUrl,
    );
    return;
  }

  if (this.currentUser === null) {
    console.log("addMessage requires a signed-in user");
    return;
  }

  const message: ChatMessage = {
    name: this.currentUser.displayName,
    profilePicUrl: this.currentUser.photoURL,
    timestamp: serverTimestamp(),
    uid: this.currentUser?.uid,
  };

  textMessage && (message.text = textMessage);
  imageUrl && (message.imageUrl = imageUrl);

  try {
    const newMessageRef = await addDoc(
      collection(this.firestore, "messages"),
      message,
    );
    return newMessageRef;
  } catch (error) {
    console.error("Error writing new message to Firebase Database", error);
    return;
  }
};

測試訊息傳送功能

  1. 建立修訂版本,並使用「張貼新的即時通訊到 Firestore」的修訂版本訊息,並推送至 GitHub 存放區。
  2. 在 Firebase 控制台中開啟應用程式託管頁面,然後等待新推出作業完成。
  3. 重新整理 EasyChat。登入後,請輸入「嗨,你好!」這類訊息,然後按一下「傳送」。這會將訊息寫入 Cloud Firestore。不過,您還沒有在實際網頁應用程式中看到資料,因為您仍然需要實作「擷取」資料 (程式碼研究室的下一節)。
  4. 您可以在 Firebase 控制台中看到新增的訊息。開啟模擬器套件 UI。在「建構」區段下方,按一下「Firestore 資料庫」 (或按一下這裡,您應該會看到包含新訊息的「訊息」集合:

6812efe7da395692.png

10. 讀取訊息

同步處理郵件

如要在應用程式中讀取訊息,您必須新增會在資料變更時觸發的可觀測項目,然後建立使用者介面元素來顯示新訊息。

您必須新增程式碼,以便監聽應用程式中新增的訊息。在這段程式碼中,您將擷取 messages 集合的快照。載入期間只會顯示最後 12 則訊息,避免顯示過長的記錄。

  1. 返回 src/app/services/chat.service.ts 檔案。
  2. 找出 loadMessages 函式。
  3. 將整個函式替換為以下程式碼。

chat.service.ts

// Loads chat message history and listens for upcoming ones.
loadMessages = () => {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(this.firestore, 'messages'), orderBy('timestamp', 'desc'), limit(12));
  // Start listening to the query.
  return collectionData(recentMessagesQuery);
}

如要監聽資料庫中的訊息,您可以使用 collection 函式針對集合建立查詢,指定要監聽的資料所屬的集合。在上述程式碼中,您聆聽的是 messages 集合 (儲存即時通訊訊息) 的變更。此外,您還能使用 limit(12) 監聽最近 12 則訊息,並使用 orderBy('timestamp', 'desc') 依日期排序訊息,藉此套用限制,以便取得 12 則最新訊息。

collectionData 函式會在背景中使用快照。當符合查詢的文件有所變更時,就會觸發回呼函式。這可能包括刪除、修改或新增郵件。詳情請參閱 Cloud Firestore 說明文件

測試同步處理訊息

  1. 建立含有「在 UI 中顯示新聊天」的修訂版本,並推送至 GitHub 存放區。
  2. 在 Firebase 控制台中開啟應用程式託管頁面,然後等待新推出作業完成。
  3. 重新整理 EasyChat。您先前在資料庫建立的訊息會顯示在 BetterChat UI 中 (請見下方說明)。您可以撰寫新郵件,這些郵件應該會立即顯示。
  4. (選用) 您可以嘗試直接在 Emulator 套件的「Firestore」部分手動刪除、修改或新增訊息;任何變更都會反映在 UI 中。

恭喜!您正在在應用程式中讀取 Cloud Firestore 文件!

angularfire-2.png

11. 新增 AI 功能

您將運用 Google AI 技術,在即時通訊應用程式中新增實用的輔助功能。

取得 Google AI API 金鑰

  1. 前往 Google AI Studio,然後按一下「Create API key」(建立 API 金鑰)
  2. 請選取您為本程式碼研究室建立的 Firebase 專案。提示是針對 Google Cloud 專案,但每個 Firebase 專案都是 Google Cloud 專案。
  3. 按一下「在現有專案中建立 API 金鑰」
  4. 複製產生的 API 金鑰

安裝擴充功能

這項擴充功能會部署 Cloud 函式,每當有新文件新增至 Firestore 的 messages 集合時,就會觸發這個 Cloud 函式。這個函式會呼叫 Gemini,並將回應寫回文件中的 response 欄位。

  1. 在「使用 Gemini API 建構聊天機器人」擴充功能頁面中,按一下「在 Firebase 控制台中安裝」
  2. 請依照系統的提示操作。在「設定擴充功能」步驟中,設定下列參數值:
    • Gemini API 供應商:Google AI
    • Google AI API 金鑰:貼上您先前建立的金鑰,然後按一下「Create secret」(建立密鑰)
    • Firestore 集合路徑:messages
    • 提示欄位:text
    • 回應欄位:response
    • 訂單欄位:timestamp
    • 背景資訊:Keep your answers short, informal, and helpful. Use emojis when possible.
  3. 按一下「安裝擴充功能」
  4. 等待擴充功能完成安裝

測試 AI 功能

CompatibilityChat 已有可讀取 AI 擴充功能回覆的程式碼。只要傳送新的即時通訊訊息進行測試,就能立即試用!

  1. 開啟 EasyChat 並傳送訊息。
  2. 不久後,你應該會在訊息旁看到彈出式回覆。結尾處有 ✨ ai generated 附註,說明內容是由生成式 AI 建立,而非真實使用者。

12. 傳送圖片

您現在將新增一個能分享圖片的功能。

雖然 Cloud Firestore 適合用來儲存結構化資料,但 Cloud Storage 更適合儲存檔案。Cloud Storage for Firebase 是一項檔案/blob 儲存服務,可用來儲存使用者透過 Google 應用程式分享的任何圖片。

將圖片儲存至 Cloud Storage

在本程式碼研究室中,您已新增用於觸發檔案選擇器對話方塊的按鈕。選取檔案後,系統會呼叫 saveImageMessage 函式,您可以取得所選檔案的參照。saveImageMessage 函式可完成以下作業:

  1. 在聊天室訊息串中建立「預留位置」聊天室訊息,讓使用者在上傳圖片時看到「載入中」的動畫。
  2. 將映像檔上傳至 Cloud Storage 到以下路徑:/<uid>/<file_name>
  3. 產生可公開讀取的圖片檔網址。
  4. 使用最新上傳的圖片檔案網址更新即時通訊訊息,以取代暫存載入圖片。

現在請新增傳送圖片的功能:

  1. 返回 src/chat.service.ts 檔案。
  2. 找出 saveImageMessage 函式。
  3. 將整個函式替換為以下程式碼。

chat.service.ts

// Saves a new message containing an image in Firestore.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
  try {
    // 1 - Add a message with a loading icon that will get updated with the shared image.
    const messageRef = await this.addMessage(null, this.LOADING_IMAGE_URL);

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${this.auth.currentUser?.uid}/${file.name}`;
    const newImageRef = ref(this.storage, 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.
    messageRef ?
    await updateDoc(messageRef, {
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    }): null;
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

測試傳送圖片

  1. 建立含有「新增張貼圖片的功能」的修訂版本,並推送至 GitHub 存放區。
  2. 在 Firebase 控制台中開啟應用程式託管頁面,然後等待新推出作業完成。
  3. 重新整理 EasyChat。登入後,按一下左下角的「圖片上傳」按鈕 angularfire-4.png,然後使用檔案選擇器選取圖片檔。如果您想要尋找圖片,不妨參考這張實用相片 (例如咖啡杯的圖片)。
  4. 應用程式 UI 中應會顯示新訊息,且會顯示所選圖片:angularfire-2.png

如果在未登入的情況下嘗試新增圖片,系統應該會顯示錯誤訊息,說明您必須登入才能新增圖片。

13. 顯示通知

您現在將新增瀏覽器通知支援功能。當聊天中有新訊息時,應用程式會通知使用者。Firebase 雲端通訊 (FCM) 是跨平台的訊息傳遞解決方案,可讓您免費傳送和接收訊息。

新增 FCM Service Worker

網頁應用程式需要接收及顯示網路通知的「Service Worker」

新增 AngularFire 時,訊息服務供應商應已完成設定,請確認 /angularfire-start/src/app/app.module.ts 的匯入區段中有下列程式碼

provideMessaging(() => {
    return getMessaging();
}),

app/app.module.ts

Service Worker 只需要載入並初始化 Firebase 雲端通訊 SDK,後者則負責顯示通知。

取得 FCM 裝置權杖

裝置或瀏覽器啟用通知功能後,您會收到裝置權杖,這個裝置權杖是用來傳送通知給特定裝置或瀏覽器。

當使用者登入時,您會呼叫 saveMessagingDeviceToken 函式。請在這裡取得瀏覽器的 FCM 裝置權杖,並將權杖儲存至 Cloud Firestore。

chat.service.ts

  1. 找出 saveMessagingDeviceToken 函式。
  2. 將整個函式替換為以下程式碼。

chat.service.ts

// Saves the messaging device token to Cloud Firestore.
saveMessagingDeviceToken= async () => {
    try {
      const currentToken = await getToken(this.messaging);
      if (currentToken) {
        console.log('Got FCM device token:', currentToken);
        // Saving the Device Token to Cloud Firestore.
        const tokenRef = doc(this.firestore, 'fcmTokens', currentToken);
        await setDoc(tokenRef, { uid: this.auth.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(this.messaging, (message) => {
          console.log(
            'New foreground notification from Firebase Messaging!',
            message.notification
          );
        });
      } else {
        // Need to request permissions to show notifications.
        this.requestNotificationsPermissions();
      }
    } catch(error) {
      console.error('Unable to get messaging token.', error);
    };
}

不過,這個程式碼一開始無法運作。為了讓您的應用程式能夠擷取裝置權杖,使用者必須授予應用程式顯示通知的權限 (程式碼研究室的下一個步驟)。

要求顯示通知的權限

如果使用者尚未授權應用程式顯示通知,您就不會獲得裝置權杖。在這種情況下,您可以呼叫 requestPermission() 方法,顯示瀏覽器對話方塊,要求取得此權限 ( 請使用支援的瀏覽器)。

8b9d0c66dc36153d.png

  1. 返回 src/app/services/chat.service.ts 檔案。
  2. 找出 requestNotificationsPermissions 函式。
  3. 將整個函式替換為以下程式碼。

chat.service.ts

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

取得裝置權杖

  1. 建立含有「新增張貼圖片的功能」的修訂版本,並推送至 GitHub 存放區。
  2. 在 Firebase 控制台中開啟應用程式託管頁面,然後等待新推出作業完成。
  3. 重新整理 EasyChat。登入後,畫面上應會顯示通知權限對話方塊:bd3454e6dbfb6723.png
  4. 按一下 [Allow]
  5. 開啟瀏覽器的 JavaScript 控制台。您應該會看到下列訊息:Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  6. 複製您的裝置權杖。在本程式碼研究室的下一階段中,您會用到這些資訊。

將通知傳送至您的裝置

現在您已取得裝置權杖,可以傳送通知了。

  1. 開啟 Firebase 控制台的「雲端通訊」分頁
  2. 按一下「新增通知」。
  3. 輸入通知標題和通知文字。
  4. 按一下畫面右側的「傳送測試訊息」
  5. 輸入從瀏覽器 JavaScript 控制台複製的裝置權杖,然後按一下加號 (「+」)
  6. 按一下「測試」

如果您的應用程式在前景執行,則 JavaScript 控制台會顯示通知。

如果您的應用程式在背景執行,瀏覽器應該會顯示通知,如以下範例所示:

de79e8638a45864c.png

14. Cloud Firestore 安全性規則

查看資料庫安全性規則

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

安全性規則應會自動更新至模擬器套件。

查看 Cloud Storage 安全性規則

Cloud Storage for 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;
    }
  }
}

您將更新規則以執行下列操作:

  • 僅允許每位使用者寫入自己的特定資料夾
  • 允許所有人讀取 Cloud Storage 中的資料
  • 請確定上傳的檔案是圖片
  • 將上傳的圖片大小上限為 5 MB

您可以使用下列規則進行這項操作:

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

15. 恭喜!

您已使用 Firebase 建構即時即時通訊網頁應用程式!

目前保固範圍

  • Firebase App Hosting
  • Firebase 驗證
  • Cloud Firestore
  • Cloud Storage 專用 Firebase SDK
  • Firebase 雲端通訊
  • Firebase Performance Monitoring

後續步驟

瞭解詳情

16. [選用] 透過 App Check 強制執行

Firebase App Check 可協助防止服務受到不必要的流量影響,並防止後端遭到濫用。在這個步驟中,您將新增憑證驗證,並透過 App Check 和 reCAPTCHA Enterprise 封鎖未經授權的用戶端。

請先啟用 App Check 和 reCAPTCHA。

啟用 reCAPTCHA Enterprise

  1. 在 Cloud 控制台中,找出並選取「安全性」下方的「reCaptcha Enterprise」
  2. 按照系統提示啟用服務,然後按一下「建立金鑰」
  3. 按照系統提示輸入顯示名稱,然後選取「網站」做為平台類型。
  4. 將已部署的網址新增至網域清單,並確認「使用核取方塊驗證」選項未選取
  5. 按一下「Create Key」,然後將產生的金鑰存放在安全位置。後續步驟會用到這項資訊。

啟用 App Check

  1. 在 Firebase 控制台中,找到左側面板中的「建構」部分。
  2. 依序點選「App Check」和「Sign-in method」分頁標籤,前往 App Check
  3. 按一下「Register」,並在系統提示時輸入 reCAPTCHA Enterprise 金鑰,然後按一下「儲存」
  4. 在 API 檢視畫面中,選取「儲存空間」,然後按一下「強制執行」。對 Cloud Firestore 執行相同操作。

系統現在應可強制執行 App Check!請重新整理應用程式,然後嘗試查看或傳送即時通訊訊息。您應該會收到以下錯誤訊息:

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

也就是說,App Check 預設會封鎖未經驗證的要求。現在,我們要為應用程式新增驗證功能。

前往 environment.ts 檔案,並將 reCAPTCHAEnterpriseKey 新增至 environment 物件。

export const environment = {
  firebase: {
    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',
  },
  reCAPTCHAEnterpriseKey: {
    key: "Replace with your recaptcha enterprise site key"
  },
};

key 的值替換成您的 reCAPTCHA Enterprise 權杖。

接著,前往 app.module.ts 檔案,並新增下列匯入項目:

import { getApp } from '@angular/fire/app';
import {
  ReCaptchaEnterpriseProvider,
  initializeAppCheck,
  provideAppCheck,
} from '@angular/fire/app-check';

在同一個 app.module.ts 檔案中,新增下列全域變數宣告:

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

在匯入內容中,使用 ReCaptchaEnterpriseProvider 新增 App Check 的初始化作業,並將 isTokenAutoRefreshEnabled 設為 true,以允許自動重新整理權杖。

imports: [
BrowserModule,
AppRoutingModule,
CommonModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAppCheck(() => {
const appCheck = initializeAppCheck(getApp(), {
  provider: new ReCaptchaEnterpriseProvider(
  environment.reCAPTCHAEnterpriseKey.key
  ),
  isTokenAutoRefreshEnabled: true,
  });
  if (location.hostname === 'localhost') {
    self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
  }
  return appCheck;
}),

如要進行本機測試,請將 self.FIREBASE_APPCHECK_DEBUG_TOKEN 設為 true。在 localhost 中重新整理應用程式時,這項操作會在控制台中記錄偵錯權杖,如下所示:

App Check debug token: CEFC0C76-7891-494B-B764-349BDFD00D00. You will need to add it to your app's App Check settings in the Firebase console for it to work.

接著,前往 Firebase 控制台中的 App Check 的 應用程式檢視畫面

按一下溢位選單,然後選取「管理偵錯權杖」

接著,按一下「Add debug token」,然後貼上控制台中的偵錯權杖。

前往 chat.service.ts 檔案,並新增下列匯入項目:

import { AppCheck } from '@angular/fire/app-check';

在同一個 chat.service.ts 檔案中,插入 App Check 和其他 Firebase 服務。

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...
  1. 建立含有「透過 App Check 封鎖未經授權的用戶端」修訂版本訊息,並推送至 GitHub 存放區。
  2. 在 Firebase 控制台中開啟應用程式託管頁面,然後等待新推出作業完成。

恭喜!App Check 現在應可在應用程式中正常運作。