AngularFire 網頁程式碼研究室

1. 總覽

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

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

課程內容

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

事前準備

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

2. 取得程式碼範例

建立 GitHub 存放區

您可以在 https://github.com/firebase/codelab-friendlychat-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 App Hosting:用於建構、代管及提供應用程式。
  • Firebase 雲端通訊:用於傳送推播通知和顯示瀏覽器彈出式通知。
  • Firebase 效能監控,收集應用程式的使用者效能資料。

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

升級 Firebase 定價方案

如要使用 Firebase 應用程式代管和 Firebase 適用的 Cloud Storage,您的 Firebase 專案必須採用即付即用 (Blaze) 定價方案,也就是說必須連結至 Cloud Billing 帳戶

  • 您必須提供付款方式 (例如信用卡),才能建立 Cloud Billing 帳戶。
  • 如果您是 Firebase 和 Google Cloud 的新手,請確認您是否符合$300 美元的抵免額和免費試用 Cloud Billing 帳戶的資格。
  • 如果您是為了參加活動而進行這個程式碼研究室,請向活動主辦單位詢問是否有任何 Cloud 抵用金。

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

  1. 在 Firebase 控制台中,選取「升級方案」
  2. 選取 Blaze 方案。按照畫面上的指示將 Cloud Billing 帳戶連結至專案。
    如果您需要在升級過程中建立 Cloud Billing 帳戶,可能需要返回 Firebase 控制台的升級流程,才能完成升級。

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

  1. 按一下網頁圖示 58d6543a156e56f9.png,建立新的 Firebase 網頁應用程式。
  2. 使用「Friendly Chat」做為應用程式的暱稱註冊。請勿勾選「Also set up Firebase Hosting for this app」旁的方塊。按一下「Register app」
  3. 在下一個步驟中,您會看到設定物件。你目前不需要這項功能。按一下 [Continue to console] (前往主控台)。

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

設定驗證方法

如要讓使用者以 Google 帳戶登入網頁應用程式,請使用 Google 登入方式。

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

設定 Cloud Firestore

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

以下說明如何在 Firebase 專案中設定 Cloud Firestore:

  1. 在 Firebase 主控台的左側面板中展開「Build」,然後選取「Firestore database」
  2. 按一下 [Create database] (建立資料庫)。
  3. 將「資料庫 ID」設為 (default)
  4. 選取資料庫的位置,然後按一下「Next」
    如果是實際應用程式,請選擇距離使用者較近的位置。
  5. 按一下「以測試模式啟動」。請詳閱安全性規則免責事項。
    在本程式碼研究室的後續部分,您將新增安全性規則來保護資料。請勿發布或公開應用程式,除非您已為資料庫新增安全性規則。
  6. 按一下「建立」

設定 Cloud Storage for Firebase

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

以下說明如何在 Firebase 專案中設定 Cloud Storage for Firebase:

  1. 在 Firebase 主控台的左側面板中,展開「Build」,然後選取「Storage」
  2. 按一下「開始使用」
  3. 選取預設儲存體值區的位置。
    US-WEST1US-CENTRAL1US-EAST1 中的值區可使用 Google Cloud Storage 的「永遠免費」方案。其他所有位置的值區都會遵循 Google Cloud Storage 的定價和用量
  4. 按一下「以測試模式啟動」。請詳閱安全性規則免責事項。
    在本程式碼研究室的後續部分,您將新增安全性規則來保護資料。請勿發布或公開應用程式,否則請為儲存空間值區新增安全規則。
  5. 按一下「建立」

4. 安裝 Firebase 指令列介面

Firebase 指令列介面 (CLI) 可讓您使用 Firebase 代管功能在本機上提供 Web 應用程式,以及將 Web 應用程式部署至 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 存放區中的分支。

在本節結束後,您將擁有一個與 GitHub 存放區連結的 App Hosting 後端,只要您將新的修訂版本推送至 main 分支,後端就會自動重新建構及發布新版應用程式。

  1. 前往 Firebase 控制台的「應用程式代管」頁面:

應用程式代管主控台的零狀態,顯示「開始使用」按鈕

  1. 按一下「開始使用」即可開始後端建立流程。請按照下列步驟設定後端:
  2. 按照第一個步驟中的提示,連結先前建立的 GitHub 存放區。
  3. 設定部署作業設定:
    1. 將根目錄保留為 /
    2. 將上線分支設為 main
    3. 啟用自動推出功能
  4. 為後端 friendlychat-codelab 命名。
  5. 在「建立或連結 Firebase 網頁應用程式」中,從「選取現有的 Firebase 網頁應用程式」下拉式選單中,選取先前設定的網頁應用程式。
  6. 按一下「完成並部署」。過一會兒,系統就會將您導向新頁面,您可以在該頁面中查看新應用程式代管後端的狀態!
  7. 推出完成後,請按一下「網域」下方的免費網域。由於 DNS 需要傳播,因此可能需要幾分鐘才能開始運作。

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

應用程式代管主控台的零狀態,顯示「開始使用」按鈕

你應該會看到 FriendlyChat 應用程式的登入畫面,但 (目前) 無法運作。

應用程式目前無法執行任何操作,但在你的協助下,很快就能運作了!

接下來,我們將建構即時通訊應用程式。

7. 匯入及設定 Firebase

設定 Firebase

您必須設定 Firebase SDK,告訴系統您使用的是哪個 Firebase 專案。

  1. 前往 Firebase 主控台中的專案設定
  2. 在「您的應用程式」資訊卡中,選取需要設定物件的應用程式別名。
  3. 在 Firebase SDK 程式碼片段窗格中選取「設定」。

您會發現系統已為您產生環境檔案 /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.firebasestorage.app",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
  },
};

查看 AngularFire 設定

您會發現在控制台中選取的功能已自動加入 /angularfire-start/src/app/app.config.ts 檔案。這樣一來,應用程式就能使用 Firebase 功能。

8. 設定使用者登入

由於 AngularFire 已在 app.config.ts 中匯入及初始化,因此現在應該可以使用了。接下來,您將使用 Firebase 驗證實作使用者登入功能。

新增授權網域

Firebase 驗證服務只允許使用者從您控管的網域清單登入。將免費的應用程式代管網域新增至網域清單:

  1. 前往「App Hosting」
  2. 複製後端的網域。
  3. 前往「驗證設定」
  4. 選擇「已授權網域」分頁標籤。
  5. 按一下「新增網域」,然後貼上 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);
    })
}

追蹤驗證狀態

如要據此更新 UI,您需要能夠檢查使用者是否已登入或登出。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,該函式會傳回可觀察的使用者。每次驗證狀態變更 (使用者登入或登出時) 就會觸發。FriendlyChat 中的 Angular 範本元件會使用這個可觀察項,更新 UI 以便重新導向、在標題列導覽中顯示使用者等等。

測試登入應用程式

  1. 建立修訂版本,並在修訂版本訊息中加入「新增 Google 驗證」字樣,然後將修訂版本推送至 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

在本節中,您將新增功能,讓使用者將新訊息寫入資料庫。使用者按下「SEND」按鈕時,系統會觸發下列程式碼片段。這會將含有訊息欄位內容的訊息物件新增至 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. 重新整理 FriendlyChat。登入後,輸入訊息 (例如「嗨!」),然後按一下「傳送」。這會將訊息寫入 Cloud Firestore。不過,您還看不到實際網頁應用程式中的資料,因為您仍需要實作擷取資料的功能 (程式碼研究室的下一節)。
  4. 您可以在 Firebase 控制台中查看新加入的訊息。開啟模擬器套件 UI。在「建構」專區下方,按一下「Firestore 資料庫」 (或按一下這裡),您應該會看到包含新訊息的「訊息」集合:

6812efe7da395692.png

10. 讀取訊息

同步處理訊息

如要讀取應用程式中的訊息,您必須新增可觀察項目,以便在資料變更時觸發,然後建立可顯示新訊息的 UI 元素。

您將新增程式碼,用來監聽應用程式中新增的訊息。在這個程式碼中,您將擷取 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. 重新整理 FriendlyChat。先前在資料庫中建立的訊息應會顯示在 FriendlyChat UI 中 (請見下方說明)。您可以隨意撰寫新訊息,這些訊息應該會立即顯示。
  4. (選用) 您可以嘗試直接在 Emulator 套件的 Firestore 專區中手動刪除、修改或新增訊息;任何變更都會反映在 UI 中。

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

angularfire-2.png

11. 新增 AI 功能

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

取得 Google AI API 金鑰

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

安裝擴充功能

這項擴充功能會部署雲端函式,每次在 Firestore 的 messages 集合中新增文件時就會觸發該函式。函式會呼叫 Gemini,並將回應寫回文件中的 response 欄位。

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

測試 AI 功能

FriendlyChat 已提供可讀取 AI 擴充功能回應的程式碼。只要傳送新的即時通訊訊息即可測試!

  1. 開啟 FriendlyChat 並傳送訊息。
  2. 過一會兒,你應該會在訊息旁看到回覆彈出式視窗。該內容結尾處有 ✨ ai generated 附註,清楚說明該內容是由生成式 AI 建立,而非真人使用者。

12. 傳送圖片

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

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

將圖片儲存至 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. 重新整理 FriendlyChat。登入後,請按一下左下方的圖片上傳按鈕 angularfire-4.png,然後使用檔案挑選器選取圖片檔案。如要尋找圖片,歡迎使用這張精美的咖啡杯圖片
  4. 應用程式的 UI 應會顯示新訊息,並顯示您選取的圖片:angularfire-2.png

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

13. 顯示通知

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

新增 FCM 服務 worker

網頁應用程式需要服務工作站,用來接收及顯示網路通知。

新增 AngularFire 時,訊息供應器應已設定完成,請確認 /angularfire-start/src/app/app.config.ts 的 imports 區段中含有以下程式碼

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

app/app.config.ts

服務工作站只需載入並初始化 Firebase 雲端通訊 SDK,即可負責顯示通知。

取得 Firebase 雲端通訊裝置權杖

在裝置或瀏覽器上啟用通知後,您會收到裝置記號。您可以使用這個裝置權杖,將通知傳送至特定裝置或特定瀏覽器。

當使用者登入時,您會呼叫 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. 重新整理 FriendlyChat。登入後,系統會顯示通知權限對話方塊:bd3454e6dbfb6723.png
  4. 按一下「允許」
  5. 開啟瀏覽器的 JavaScript 控制台。您應該會看到下列訊息:Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  6. 複製裝置權杖。您會在程式碼研究室的後續階段中使用。

傳送通知到你的裝置

取得裝置權杖後,您就可以傳送通知。

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

如果應用程式處於前景,您會在 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 安全性規則

Firebase 專用 Cloud Storage 會使用特定的規則語言定義存取權、安全性和資料驗證。

在本程式碼研究室一開始設定 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 控制台中,找出並選取「Security」(安全性) 下方的「reCaptcha Enterprise」
  2. 依提示啟用服務,然後按一下「Create Key」(建立金鑰)
  3. 依提示輸入顯示名稱,然後選取「網站」做為平台類型。
  4. 將已部署的網址加入網域清單,並確認「使用核取方塊驗證」選項未選取
  5. 按一下「建立金鑰」,然後將產生的金鑰存放在安全的地方。稍後在本步驟中會用到這項資訊。

啟用 App Check

  1. 在 Firebase 控制台中,找出左側面板中的「建構」專區。
  2. 依序點選「App Check」和「登入方式」分頁標籤,前往「App Check」
  3. 按一下「註冊」,然後在系統顯示提示時輸入 reCaptcha Enterprise 金鑰,接著按一下「儲存」
  4. 在「API 檢視」中,選取「Storage」,然後按一下「Enforce」。請對 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.firebasestorage.app',
    messagingSenderId: 'SENDER_ID',
    appId: 'APP_ID',
    measurementId: 'G-MEASUREMENT_ID',
  },
  reCAPTCHAEnterpriseKey: {
    key: "Replace with your recaptcha enterprise site key"
  },
};

key 的值替換為 reCaptcha Enterprise 權杖。

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

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

在同一個 app.config.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。