AngularFire Web 程式碼實驗室

1. 概述

在此 Codelab 中,您將學習如何使用AngularFire透過使用 Firebase 產品和服務實作和部署聊天用戶端來建立 Web 應用程式。

angularfire-2.png

你將學到什麼

  • 使用 Angular 和 Firebase 建立 Web 應用。
  • 使用 Cloud Firestore 和 Cloud Storage for Firebase 同步資料。
  • 使用 Firebase 驗證對您的使用者進行身份驗證。
  • 在 Firebase 託管上部署您的 Web 應用程式。
  • 使用 Firebase 雲端訊息傳遞發送通知。
  • 收集您的網路應用程式的效能數據。

你需要什麼

  • 您選擇的 IDE/文字編輯器,例如WebStormAtomSublimeVS Code
  • 套件管理器npm ,通常隨Node.js一起提供
  • 終端/控制台
  • 您選擇的瀏覽器,例如 Chrome
  • Codelab的範例程式碼(有關如何取得程式碼,請參閱Codelab的下一步。)

2. 取得範例程式碼

從命令列克隆 Codelab 的GitHub 儲存庫

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

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

導入入門應用程式

使用 IDE,從複製的儲存庫中開啟或匯入 📁 angularfire-start目錄。這個 📁 angularfire-start目錄包含 Codelab 的起始程式碼,它將是一個功能齊全的聊天 Web 應用程式。

3. 建立並設定 Firebase 項目

創建 Firebase 項目

  1. 登入Firebase
  2. 在 Firebase 控制台中,按一下新增項目,然後將您的 Firebase 專案命名為FriendlyChat 。請記住您的 Firebase 專案的專案 ID。
  3. 取消選取為此專案啟用 Google Analytics
  4. 按一下「建立專案」

您要建立的應用程式使用可用於網頁應用的 Firebase 產品:

  • Firebase 驗證可輕鬆讓您的使用者登入您的應用程式。
  • Cloud Firestore將結構化資料保存在雲端,並在資料變更時獲得即時通知。
  • Cloud Storage for Firebase將檔案保存在雲端。
  • Firebase Hosting用於託管和服務您的資產。
  • Firebase Cloud Messaging用於傳送推播通知並顯示瀏覽器彈出通知。
  • Firebase 效能監控,用於收集應用程式的使用者效能資料。

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

將 Firebase Web 應用程式新增至專案中

  1. 按一下網路圖示58d6543a156e56f9.png建立一個新的 Firebase Web 應用程式。
  2. 使用暱稱“Friendly Chat”註冊應用程序,然後選中“同時為此應用程式設定 Firebase 託管”旁邊的方塊。點擊註冊應用程式
  3. 在下一步中,您將看到一個配置物件。僅將 JS 物件(而不是周圍的 HTML)複製到firebase-config.js

註冊網頁應用程式截圖

啟用 Google登入以進行 Firebase 身份驗證

要允許用戶使用其 Google 帳戶登入網路應用程序,您將使用Google登入方法。

您需要啟用Google登入:

  1. 在 Firebase 控制台中,找到左側面板中的「建置」部分。
  2. 按一下「驗證」 ,然後按一下「登入方法」標籤(或按一下此處直接前往此處)。
  3. 啟用Google登入供應商,然後按一下「儲存」
  4. 將應用程式面向公眾的名稱設定為「友善聊天」 ,然後從下拉式選單中選擇項目支援電子郵件
  5. Google Cloud Console中配置 OAuth 同意畫面並新增徽標:

d89fb3873b5d36ae.png

啟用 Cloud Firestore

Web 應用程式使用Cloud Firestore儲存聊天訊息並接收新的聊天訊息。

您需要啟用 Cloud Firestore:

  1. 在 Firebase 控制台的「建置」部分中,按一下Firestore 資料庫
  2. 按一下 Cloud Firestore 窗格中的建立資料庫

729991a081e7cd5.png

  1. 選擇「以測試模式啟動」選項,然後在閱讀有關安全規則的免責聲明後按一下「下一步」

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

77e4986cbeaf9dee.png

  1. 設定 Cloud Firestore 資料的儲存位置。您可以將其保留為預設值或選擇離您較近的區域。按一下「完成」以配置 Firestore。

9f2bb0d4e7ca49c7.png

啟用雲端儲存

此 Web 應用程式使用 Cloud Storage for Firebase 來儲存、上傳和分享圖片。

您需要啟用雲端儲存:

  1. 在 Firebase 控制台的「建置」部分中,按一下「儲存」
  2. 如果沒有「開始」按鈕,則表示雲端儲存已啟用,您無需執行下列步驟。
  3. 單擊開始
  4. 閱讀有關 Firebase 專案安全規則的免責聲明,然後按一下「下一步」

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

62f1afdcd1260127.png

  1. 預先選擇的 Cloud Storage 位置與您為 Cloud Firestore 資料庫選擇的區域相同。按一下“完成”完成設定。

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 應用程式模板,以從應用程式的本機目錄(您先前在 Codelab 中複製的儲存庫)中提取應用程式的 Firebase 託管配置。但要提取配置,您需要將應用程式與 Firebase 專案關聯。

  1. 確保您的命令列正在存取應用程式的本機angularfire-start目錄。
  2. 透過執行以下命令將您的應用程式與 Firebase 專案關聯:
firebase use --add
  1. 出現提示時,選擇您的專案 ID ,然後為您的 Firebase 專案指定一個別名。

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

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

5.安裝AngularFire

在運行專案之前,請確保已設定 Angular CLI 和 AngularFire。

  1. 在控制台中,執行以下命令:
npm install -g @angular/cli
  1. 然後,在angularfire-start目錄的控制台中,執行以下 Angular CLI 命令:
ng add @angular/fire

這將為您的專案安裝所有必需的依賴項。

  1. 出現提示時,請選擇在 Firebase 控制台中設定的功能( ng deploy -- hostingAuthenticationFirestoreCloud Functions (callable)Cloud MessagingCloud Storage ),然後依照控制台上的指示操作。

6. 在本地運行入門應用程式

現在您已匯入並設定了項目,您已準備好首次執行 Web 應用程式。

  1. angularfire-start目錄的控制台中,執行以下 Firebase CLI 指令:
firebase emulators:start
  1. 您的命令列應顯示以下回應:
✔  hosting: Local server: http://localhost:5000

您正在使用Firebase 託管模擬器在本地為我們的應用程式提供服務。現在應該可以從http://localhost:5000存取該 Web 應用程式。提供位於src子目錄下的所有檔案。

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

您應該會看到FriendlyChat應用程式的UI,它(尚未!)運行:

AngularFire-2.png

該應用程式現在無法執行任何操作,但在您的幫助下,很快就會!到目前為止,您只為您設計了 UI。

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

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",
    databaseURL: "https://PROJECT_ID.firebaseio.com",
    projectId: "PROJECT_ID",
    storageBucket: "PROJECT_ID.appspot.com",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
    measurementId: "G-MEASUREMENT_ID",
  },
};

導入 AngularFire

您會發現您在控制台中選擇的功能已自動路由到/angularfire-start/src/app/app.module.ts檔案中。這允許您的應用程式使用 Firebase 特性和功能。但是,要在本機環境中進行開發,您需要連接它們才能使用模擬器套件。

  1. /angularfire-start/src/app/app.module.ts中,找到imports部分,並修改提供的函數以在非生產環境中連接到模擬器套件。
// ...

import { provideAuth,getAuth, connectAuthEmulator } from '@angular/fire/auth';
import { provideFirestore,getFirestore, connectFirestoreEmulator } from '@angular/fire/firestore';
import { provideFunctions,getFunctions, connectFunctionsEmulator } from '@angular/fire/functions';
import { provideMessaging,getMessaging } from '@angular/fire/messaging';
import { provideStorage,getStorage, connectStorageEmulator } from '@angular/fire/storage';

// ...

provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => {
    const auth = getAuth();
    if (location.hostname === 'localhost') {
        connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
    }
    return auth;
}),
provideFirestore(() => {
    const firestore = getFirestore();
    if (location.hostname === 'localhost') {
        connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
    }
    return firestore;
}),
provideFunctions(() => {
    const functions = getFunctions();
    if (location.hostname === 'localhost') {
        connectFunctionsEmulator(functions, '127.0.0.1', 5001);
    }
    return functions;
}),
provideStorage(() => {
    const storage = getStorage();
    if (location.hostname === 'localhost') {
        connectStorageEmulator(storage, '127.0.0.1', 5001);
    }
    return storage;
}),
provideMessaging(() => {
    return getMessaging();
}),

// ...

app.module.ts

在此 Codelab 中,您將使用 Firebase 驗證、Cloud Firestore、雲端儲存、雲端訊息傳遞和效能監控,因此您將匯入它們的所有程式庫。在您未來的應用程式中,請確保您僅匯入所需的 Firebase 部分,以縮短應用程式的載入時間。

8. 設定使用者登入

AngularFire 現在應該可以使用了,因為它是在app.module.ts中導入並初始化的。您現在將使用Firebase Authentication實現使用者登入。

使用 Google 登入對您的使用者進行身份驗證

在應用程式中,當使用者點擊「使用 Google 登入」按鈕時,就會觸發login功能。 (您已經進行了設定!)對於此 Codelab,您希望授權 Firebase 使用 Google 作為身分提供者。您將使用彈出窗口,但 Firebase 還提供其他幾種方法

  1. angularfire-start目錄的子目錄/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;
    })
}

當使用者點擊「登出」按鈕時,會觸發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,您需要一種方法來檢查使用者是否登入或登出。使用 Firebase 驗證,您可以擷取每次驗證狀態變更時將觸發的使用者狀態的可觀察值。

  1. 返回檔案src/app/services/chat.service.ts
  2. 找出變數賦值user$
  3. 將整個作業替換為以下程式碼。

chat.service.ts

// Observable user
user$ = user(this.auth);

上面的程式碼呼叫 AngularFire 函數user ,它會傳回一個可觀察的使用者。每次身份驗證狀態變更時(當使用者登入或登出時)都會觸發它。此時,您將更新 UI 以進行重定向、在標題導航中顯示使用者等。所有這些 UI 部分都已實作。

測試登入應用程式

  1. 如果您的應用程式仍在運行,請在瀏覽器中刷新您的應用程式。否則,請在命令列上運行firebase emulators:start以開始從http://localhost:5000提供應用程序,然後在瀏覽器中打開它。
  2. 使用登入按鈕和您的 Google 帳戶登入該應用程式。如果您看到錯誤訊息,指出auth/operation-not-allowed ,請檢查以確保您在 Firebase 控制台中啟用了 Google Sign-in 作為驗證提供者。
  3. 登入後,應顯示您的個人資料圖片和使用者名稱: 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>> => {
    let data: any;
    try {
      this.user$.subscribe(async (user) => 
      { 
        if(textMessage && textMessage.length > 0) {
          data =  await addDoc(collection(this.firestore, 'messages'), {
            name: user?.displayName,
            text: textMessage,
            profilePicUrl: user?.photoURL,
            timestamp: serverTimestamp(),
            uid: user?.uid
          })}
          else if (imageUrl && imageUrl.length > 0) {
            data =  await addDoc(collection(this.firestore, 'messages'), {
              name: user?.displayName,
              imageUrl: imageUrl,
              profilePicUrl: user?.photoURL,
              timestamp: serverTimestamp(),
              uid: user?.uid
            });
          }
          return data;
        }
      );
    }
    catch(error) {
      console.error('Error writing new message to Firebase Database', error);
      return;
    }
}

測試發送訊息

  1. 如果您的應用程式仍在運行,請在瀏覽器中刷新您的應用程式。否則,請在命令列上運行firebase emulators:start以開始從http://localhost:5000提供應用程序,然後在瀏覽器中打開它。
  2. 登入後,輸入一條訊息,例如“嘿那裡!”,然後點擊“發送” 。這會將訊息寫入 Cloud Firestore。但是,您還不會在實際的 Web 應用程式中看到數據,因為您仍然需要實作資料檢索(Codelab 的下一部分)。
  3. 您可以在 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. 如果您的應用程式仍在運行,請在瀏覽器中刷新您的應用程式。否則,請在命令列上運行firebase emulators:start以開始從http://localhost:5000提供應用程序,然後在瀏覽器中打開它。
  2. 您先前在資料庫中建立的訊息應顯示在FriendlyChat UI 中(請參閱下文)。隨意寫新消息;它們應該立即出現。
  3. (可選)您可以嘗試直接在模擬器套件的Firestore部分中手動刪除、修改或新增訊息;任何變更都應反映在 UI 中。

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

AngularFire-2.png

11.發送影像

您現在將新增共享圖像的功能。

雖然 Cloud Firestore 適合儲存結構化數據,但 Cloud Storage 更適合儲存檔案。 Cloud Storage for Firebase是一種檔案/blob 儲存服務,您將使用它來儲存使用者使用我們的應用程式共享的任何映像。

將影像儲存到雲端存儲

在此 Codelab 中,您已經新增了一個可觸發文件選擇器對話方塊的按鈕。選擇檔案後,將呼叫saveImageMessage函數,您可以獲得對所選檔案的引用。 saveImageMessage函數完成以下任務:

  1. 在聊天來源中建立「佔位符」聊天訊息,以便使用者在您上傳圖像時看到「正在載入」動畫。
  2. 將映像檔上傳到 Cloud Storage 的以下路徑: /<uid>/<file_name>
  3. 產生圖像檔案的公共可讀 URL。
  4. 使用新上傳的圖像檔案的 URL 代替臨時載入圖像來更新聊天訊息。

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

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

聊天服務.ts

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
  try {
    // 1 - You 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. 如果您的應用程式仍在運行,請在瀏覽器中刷新您的應用程式。否則,請在命令列上運行firebase emulators:start以開始從http://localhost:5000提供應用程序,然後在瀏覽器中打開它。
  2. 登入後,點擊左下角圖片上傳按鈕angularfire-4.png並使用檔案選擇器選擇圖像檔案。如果您正在尋找圖像,請隨意使用這張漂亮的咖啡杯圖片
  3. 應用程式的 UI 中應出現一條新訊息,其中包含您選擇的圖像: AngularFire-2.png

如果您在未登入的情況下嘗試新增圖像,您應該會看到錯誤訊息,告訴您必須登入才能新增圖像。

12.顯示通知

您現在將新增對瀏覽器通知的支援。當聊天中發布新消息時,該應用程式將通知用戶。 Firebase Cloud Messaging (FCM) 是一種跨平台訊息傳遞解決方案,可讓您免費可靠地傳遞訊息和通知。

新增 FCM 服務工作線程

Web 應用程式需要一個Service Worker來接收和顯示 Web 通知。

新增 AngularFire 時應該已經設定了訊息提供程序,請確保/angularfire-start/src/app/app.module.ts的導入部分中存在以下程式碼

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

app/app.module.ts

Service Worker 只需載入並初始化 Firebase Cloud Messaging 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);
    };
}

但是,此程式碼最初不起作用。為了讓您的應用程式能夠檢索裝置令牌,使用者需要授予您的應用程式顯示通知的權限(Codelab 的下一步)。

請求顯示通知的權限

當使用者尚未授予您的應用程式顯示通知的權限時,您將不會獲得裝置令牌。在這種情況下,您呼叫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. 如果您的應用程式仍在運行,請在瀏覽器中刷新您的應用程式。否則,請在命令列上運行firebase emulators:start以開始從http://localhost:5000提供應用程序,然後在瀏覽器中打開它。
  2. 登入後,應出現通知權限對話框: bd3454e6dbfb6723.png
  3. 按一下“允許”
  4. 開啟瀏覽器的 JavaScript 控制台。您應該會看到以下訊息: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. 複製您的設備令牌。您將在 Codelab 的下一階段需要它。

向您的裝置發送通知

現在您已擁有裝置令牌,您可以發送通知。

  1. 開啟Firebase 控制台的「雲端訊息傳遞」標籤
  2. 點擊“新通知”
  3. 輸入通知標題和通知文字。
  4. 在螢幕右側,按一下“發送測試訊息”
  5. 輸入您從瀏覽器的 JavaScript 控制台複製的裝置令牌,然後按一下加號 (“+”)
  6. 點擊“測試”

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

如果您的應用程式在背景執行,則瀏覽器中應顯示一則通知,如下例所示:

de79e8638a45864c.png

13.Cloud Firestore 安全性規則

查看資料庫安全規則

Cloud Firestore 使用特定的規則語言來定義存取權限、安全性和資料驗證。

在本 Codelab 開始時設定 Firebase 專案時,您選擇使用「測試模式」預設安全規則,以便不限制對資料儲存區的存取。在Firebase 控制台的「資料庫」部分的「規則」標籤中,您可以檢視和修改這些規則。

現在,您應該看到預設規則,這些規則不限制對資料儲存的存取。這意味著任何用戶都可以讀取和寫入資料儲存中的任何集合。

rules_version = '2';

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

您將使用以下規則更新規則以限制事物:

firestore.規則

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

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

Firebase 提供託管服務來為您的資產和 Web 應用程式提供服務。您可以使用 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. 確保您的命令列正在存取應用程式的本機angularfire-start目錄。
  2. 透過執行以下命令將檔案部署到 Firebase 專案:
ng deploy

然後選擇 Firebase 選項,並按照命令列中的提示進行操作。

  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. 訪問您的 Web 應用程序,該應用程式現在已在您自己的兩個 Firebase 子網域中使用 Firebase 託管完全託管在全球 CDN 上:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

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

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

前往專案的 Firebase 控制台託管部分,查看有用的託管資訊和工具,包括部署歷史記錄、回滾到應用程式先前版本的功能以及設定自訂網域的工作流程。

15. 恭喜!

您已使用 Firebase 建立了即時聊天 Web 應用程式!

您所涵蓋的內容

  • Firebase 身份驗證
  • 雲端Firestore
  • 適用於雲端儲存的 Firebase SDK
  • Firebase 雲端訊息傳遞
  • Firebase 效能監控
  • Firebase 託管

下一步

了解更多

16. [可選] 透過應用程式檢查強制執行

Firebase App Check可協助保護您的服務免受不必要的流量的影響,並協助保護您的後端免遭濫用。在此步驟中,您將新增憑證驗證並使用 App Check 和reCAPTCHA Enterprise阻止未經授權的用戶端。

首先,您需要啟用 App Check 和 reCaptcha。

啟用 reCaptcha Enterprise

  1. 在 Cloud 控制台中,找到並選擇「安全性」下的reCaptcha Enterprise
  2. 根據提示啟用服務,然後按一下「建立金鑰」
  3. 根據提示輸入顯示名稱,平台類型選擇「網站」
  4. 將您部署的 URL 新增至網域清單中,並確保未選擇「使用複選框質詢」選項。
  5. 按一下「建立金鑰」 ,並將產生的金鑰儲存在某處以妥善保管。您稍後將在此步驟中需要它。

啟用應用程式檢查

  1. 在 Firebase 控制台中,找到左側面板中的「建置」部分。
  2. 按一下App Check ,然後按一下登入方法標籤以導覽至App Check
  3. 按一下「註冊」並在出現提示時輸入您的 reCaptcha Enterprise 金鑰,然後按一下「儲存」
  4. 在 API 視圖中,選擇儲存並按一下強制。對Cloud Firestore執行相同的動作。

現在應該強制執行應用程式檢查!刷新您的應用程式並嘗試查看或發送聊天訊息。您應該收到錯誤訊息:

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 的應用程式檢視

按一下溢出選單,然後選擇管理偵錯令牌

然後,按一下「新增偵錯令牌」並根據提示從控制台貼上偵錯令牌。

導航到chat.service.ts文件,然後新增以下導入:

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

在同一個chat.service.ts檔案中,將 App Check 與其他 Firebase 服務一起注入。

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...

恭喜! App Check 現在應該可以在您的應用程式中運行。