Save the date - Google I/O returns May 18-20. Register to get the most out of the digital experience: Build your schedule, reserve space, participate in Q&As, earn Google Developer profile badges, and more. Register now
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

了解適用於Web的Firebase

在此代碼實驗室中,您將學習Firebase的一些基礎知識,以創建交互式Web應用程序。您將使用多種Firebase產品構建和部署事件RSVP和留言簿聊天應用程序。

59abdefbcc23bbbe.png

您將學到什麼

  • 使用Firebase身份驗證和FirebaseUI對用戶進行身份驗證。
  • 使用Cloud Firestore同步數據。
  • 編寫Firebase安全規則以保護數據庫。
  • 在Firebase託管上部署Web應用程序。

你需要什麼

  • 您選擇的瀏覽器,例如Chrome。
  • 訪問stackblitz.com (無需帳戶或登錄)。
  • 一個Google帳戶,例如一個Gmail帳戶。我們建議您已用於GitHub帳戶的電子郵件帳戶。這使您可以使用StackBlitz中的高級功能。
  • 該代碼實驗室的示例代碼。請參閱下一步以獲取代碼。

在此代碼實驗室中,您將使用StackBlitz (一個在線編輯器,其中集成了多個Firebase工作流程)來構建和部署應用程序。 Stackblitz不需要安裝軟件或特殊的StackBlitz帳戶。

StackBlitz使您可以與他人共享項目。擁有您的StackBlitz項目URL的其他人可以看到您的代碼並分叉您的項目,但他們無法編輯您的StackBlitz項目。

  1. 轉到此URL作為起始代碼: https : //stackblitz.com/edit/firebase-gtk-web-start
  2. 在StackBlitz頁面的頂部,單擊Forkf5135360aef481cc.png

現在,您已經擁有一個起始代碼的副本作為您自己的StackBlitz項目。由於您@anonymous ,因此您的帳戶稱為@anonymous ,但是該項目具有唯一的名稱以及唯一的URL。您的所有文件和更改都保存在此StackBlitz項目中。

該代碼實驗室的起始材料為Web應用程序提供了一些結構,包括一些樣式表和該應用程序的幾個HTML容器。在本代碼實驗室的後面,您將把這些容器連接到Firebase。

首先,讓我們更加熟悉StackBlitz界面。

  1. 在StackBlitz中,打開index.html文件。
  2. 找到event-details-containerdescription-container ,然後嘗試編輯一些事件詳細信息。

在編輯文本時,StackBlitz中的自動頁面重新加載會顯示新的事件詳細信息。很好,是嗎?

<!-- ... -->

<div id="app">
  <img src="..." />

  <section id="event-details-container">
     <h1>Firebase Meetup</h1>

     <p><i class="material-icons">calendar_today</i> October 30</p>
     <p><i class="material-icons">location_city</i> San Francisco</p>

  </section>

  <hr>

  <section id="firebaseui-auth-container"></section>

  <section id="description-container">
     <h2>What we'll be doing</h2>
     <p>Join us for a day full of Firebase Workshops and Pizza!</p>
  </section>
</div>



<!-- ... -->

您的應用預覽應如下所示:

應用預覽

908cc57ce3a5b5fe.png

顯示事件信息對您的客人非常有用,但是僅顯示事件對任何人都沒有幫助。讓我們向該應用程序添加一些動態功能。為此,您需要將Firebase連接到您的應用程序。要開始使用Firebase,您需要創建並設置一個Firebase項目。

創建一個Firebase項目

  1. 登錄到Firebase
  2. 在Firebase控制台中,單擊“添加項目” (或“創建項目” ),然後將您的Firebase項目命名為Firebase-Web-Codelab

a67c239f8cc7f4b5.png

  1. 單擊項目創建選項。如果出現提示,請接受Firebase條款。跳過設置Google Analytics(分析)的步驟,因為您不會為此應用使用Analytics(分析)。

要了解有關Firebase項目的更多信息,請參閱了解Firebase項目

您正在構建的應用程序使用了可用於Web應用程序的幾種Firebase產品:

  • Firebase身份驗證Firebase UI ,可輕鬆允許您的用戶登錄您的應用。
  • Cloud Firestore可將結構化數據保存在雲上,並在數據更改時立即獲得通知。
  • Firebase安全規則以保護您的數據庫。
  • Firebase Hosting託管和服務您的資產。

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

為Firebase身份驗證啟用電子郵件登錄

要允許用戶登錄Web應用程序,您將為此代碼實驗室使用“電子郵件/密碼”登錄方法:

  1. 在Firebase控制台中,單擊左側面板中的“開發”。
  2. 單擊身份驗證,然後單擊登錄方法選項卡(或單擊此處直接轉到登錄方法選項卡)。
  3. 在“登錄提供者”列表中單擊“電子郵件/密碼”,將“啟用”開關設置為打開位置,然後單擊“保存”4c88427cfd869bee.png

啟用Cloud Firestore

該Web應用程序使用Cloud Firestore來保存聊天消息並接收新的聊天消息。

啟用Cloud Firestore:

  1. 在Firebase控制台的“開發”部分中,單擊“數據庫”
  2. Cloud Firestore下,單擊“創建數據庫”3ce19fd6467e51c5.png
  1. 選擇在測試模式下啟動選項。閱讀有關安全規則的免責聲明。測試模式可確保您在開發過程中可以自由地寫入數據庫。單擊下一步56369cebb9300eb.png
  1. 選擇數據庫的位置(您可以只使用默認位置)。請注意,此位置以後無法更改。 32f815f4648c3174.png
  2. 單擊完成

現在,您已經創建了Firebase項目並啟用了一些服務,您需要告訴您要使用Firebase的代碼以及要使用的Firebase項目。

添加Firebase庫

為了使您的應用程序使用Firebase,您需要將Firebase庫添加到該應用程序。如Firebase文檔中所述,有多種方法可以執行此操作。例如,您可以從Google的CDN中添加庫,也可以使用npm在本地安裝它們,然後在使用Browserify的情況下將它們打包在您的應用中。

StackBlitz提供自動捆綁功能,因此您可以使用import語句添加Firebase庫。

要構建此應用,請使用Firebase身份驗證,FirebaseUI和Cloud Firestore庫。對於此代碼實驗室,以下行已包含在index.js文件的頂部:

// Import stylesheets
import "./style.css";

// Firebase App (the core Firebase SDK) is always required
// and must be listed first
import firebase from "firebase/app";

// Add the Firebase products that you want to use
import "firebase/auth";
import "firebase/firestore";

import * as firebaseui from "firebaseui";

將Firebase Web應用程序添加到項目中

  1. 返回Firebase控制台,單擊左上角的“項目概述” ,導航到項目的概述頁面。
  2. 在項目概述頁面的中心,單擊Web圖標b286f3d215e1f578.png創建一個新的Firebase Web應用程序。 c167e9526fad2825.png
  3. 使用暱稱“ Web應用程序”註冊該應用程序
  4. 對於此代碼實驗室,請不要選中也為此應用程序設置Firebase託管旁邊的框。現在,您將使用StackBlitz的預覽窗格。
  5. 點擊註冊應用c85ac8aa351e2560.png
  6. Firebase配置對象複製到剪貼板。 ed1e598c6132f734.png
  7. 單擊繼續進行控制台

將Firebase配置對象添加到您的應用中:

  1. 返回StackBlitz,轉到index.js文件。
  2. 找到“在Add Firebase project configuration object here註釋行,然後Add Firebase project configuration object here註釋下方粘貼您的配置代碼段。
  3. 添加initializeApp函數調用以使用您獨特的Firebase項目配置來設置Firebase。
// ...

// Add Firebase project configuration object here
var firebaseConfig = {
  apiKey: "random-unique-string",
  authDomain: "your-projectId.firebaseapp.com",
  databaseURL: "https://your-projectId.firebaseio.com",
  projectId: "your-projectId",
  storageBucket: "your-projectId.appspot.com",
  messagingSenderId: "random-unique-string",
  appId: "random-unique-string",
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

現在,您已經將Firebase添加到應用程序中了,您可以設置一個RSVP按鈕,該按鈕使用Firebase Authentication來註冊人員。

使用電子郵件登錄和FirebaseUI對您的用戶進行身份驗證

您需要一個RSVP按鈕,提示用戶使用其電子郵件地址登錄。您可以通過將FirebaseUI掛接到RSVP按鈕來執行此操作。FirebaseUI是一個庫,可在Firebase Auth的基礎上為您提供預構建的UI。

FirebaseUI需要進行以下兩項配置(請參閱文檔中的選項):

  1. 告訴FirebaseUI您要使用“電子郵件/密碼”登錄方法。
  2. 處理成功登錄的回調,並返回false以避免重定向。您不希望刷新頁面,因為您正在構建單頁Web應用程序。

首先,添加代碼以初始化FirebaseUI:

  1. 在StackBlitz中,轉到index.js文件。請注意,已經提供了FirebaseUI配置。
  2. index.js,的底部index.js,添加FirebaseUI初始化語句,如下所示:
// ...
// Initialize the FirebaseUI widget using Firebase
const ui = new firebaseui.auth.AuthUI(firebase.auth());

接下來,在HTML中添加一個RSVP按鈕:

  1. 在StackBlitz中,轉到index.html文件。
  2. 如以下示例所示,在event-details-container添加用於RSVP按鈕的HTML。

請小心使用如下所示的相同id值,因為在此代碼實驗室中, index.js文件中已經存在這些特定ID的鉤子。

請注意,在index.html文件中,有一個ID為firebaseui-auth-container 。這是您將傳遞給FirebaseUI來保留登錄名的ID。

<!-- ... -->

<section id="event-details-container">
    <!-- ... -->
    <!-- ADD THE RSVP BUTTON HERE -->
    <button id="startRsvp">RSVP</button>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<!-- ... -->

應用預覽

ab9ad7d61bb7b28c.png

  1. 在RSVP按鈕上設置偵聽器,然後調用FirebaseUI啟動函數。這告訴FirebaseUI您想查看登錄窗口。將以下代碼添加到index.js的底部:
// ... 
// At the bottom

// Listen to RSVP button clicks
startRsvpButton.addEventListener("click",
 () => {
      ui.start("#firebaseui-auth-container", uiConfig);
});

測試登錄到應用程序

  1. 在StackBlitz的預覽窗口中,單擊RSVP按鈕以登錄該應用程序。
  • 對於此代碼實驗室,您可以使用任何電子郵件地址,甚至是虛假的電子郵件地址,因為您沒有為此代碼實驗室設置電子郵件驗證步驟。
  • 如果您看到錯誤消息,說明auth/operation-not-allowedThe given sign-in provider is disabled for this Firebase project ,請檢查以確保已在Firebase控制台中啟用了Email / Password作為登錄提供程序。
  1. 轉到Firebase控制台中的“ 身份驗證”儀表板。在“用戶”標籤中,您應該看到您輸入的用於登錄該應用程序的帳戶信息。

應用預覽

3024f90b52ad55fe.png

682fc0eca86a99fc.png

將身份驗證狀態添加到UI

現在,確保用戶界面反映了您已登錄的事實。

您將使用Firebase身份驗證狀態偵聽器回調,只要用戶的登錄狀態發生更改,該回調就會得到通知。如果當前有用戶,則將“ RSVP”按鈕切換為“註銷”按鈕。

  1. 在StackBlitz中,轉到index.js文件。
  2. 在底部添加以下代碼:
// ...
// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user)=> {
  if (user) {
    startRsvpButton.textContent = "LOGOUT"
  }
  else {
    startRsvpButton.textContent = "RSVP"
  }
});
  1. 在按鈕偵聽器中,檢查是否有當前用戶並將其註銷。為此,將當前的startRsvpButton.addEventListener替換為以下內容:
// ...
// Called when the user clicks the RSVP button
startRsvpButton.addEventListener("click",
 () => {
    if (firebase.auth().currentUser) {
      // User is signed in; allows user to sign out
      firebase.auth().signOut();
    } else {
      // No user is signed in; allows user to sign in
      ui.start("#firebaseui-auth-container", uiConfig);
    }
});

現在,該按鈕應顯示LOGOUT ,並在單擊時切換回RSVP

應用預覽

4c540450924f1607.png

了解用戶的到來是很棒的,但是讓我們在應用程序中給客人做些其他的事情。如果他們可以在留言簿中留言,該怎麼辦?他們可以分享他們興奮的到來原因或希望見到誰。

要存儲用戶在應用程序中編寫的聊天消息,您將使用Cloud Firestore

資料模型

Cloud Firestore是NoSQL數據庫,數據庫中存儲的數據分為集合,文檔,字段和子集合。您會將聊天的每個消息作為文檔存儲在稱為guestbook的頂級集合中。

b447950f9f993789.png

將消息添加到Firestore

在本部分中,您將添加用於用戶將新消息寫入數據庫的功能。首先,為UI元素(消息字段和發送按鈕)添加HTML,然後添加將這些元素掛鉤到數據庫的代碼。

要添加消息字段和發送按鈕的UI元素,請執行以下操作:

  1. 在StackBlitz中,轉到index.html文件。
  2. 找到guestbook-container ,並添加以下HTML以創建帶有消息輸入字段和發送按鈕的表單。
<!-- ... -->

 <section id="guestbook-container">
   <h2>Discussion</h2>

   <form id="leave-message">
     <label>Leave a message: </label>
     <input type="text" id="message">
     <button type="submit">
       <i class="material-icons">send</i>
       <span>SEND</span>
     </button>
   </form>

 </section>

<!-- ... -->

應用預覽

4a892284443cf73d.png

用戶單擊“發送”按鈕將觸發以下代碼段。它將消息輸入字段的內容添加到數據庫的guestbook集合中。具體來說, add方法將消息內容添加到guestbook集合的新文檔(具有自動生成的ID)中。

  1. 在StackBlitz中,轉到index.js文件。
  2. 在文件的底部,添加以下代碼。

請注意, firebase.auth().currentUser.uid是對Firebase身份驗證為所有登錄用戶提供的自動生成的唯一ID的引用。

// ..
// Listen to the form submission
form.addEventListener("submit", (e) => {
 // Prevent the default form redirect
 e.preventDefault();
 // Write a new message to the database collection "guestbook"
 firebase.firestore().collection("guestbook").add({
   text: input.value,
   timestamp: Date.now(),
   name: firebase.auth().currentUser.displayName,
   userId: firebase.auth().currentUser.uid
 })
 // clear message input field
 input.value = ""; 
 // Return false to avoid redirect
 return false;
});

僅向登錄用戶顯示留言簿

您不希望任何人看到客人的聊天。確保聊天安全的一件事是僅允許登錄用戶查看留言簿。也就是說,對於您自己的應用程序,您還需要使用Firebase安全規則來保護數據庫。 (稍後在代碼實驗室中將提供有關安全規則的更多信息。)

  1. 在StackBlitz中,轉到index.js文件。
  2. 編輯onAuthStateChanged偵聽器以隱藏和顯示留言簿。
// ...
// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user) => {
 if (user){
   startRsvpButton.textContent = "LOGOUT";
   // Show guestbook to logged-in users
   guestbookContainer.style.display = "block";
 }
 else{
   startRsvpButton.textContent = "RSVP";
   // Hide guestbook for non-logged-in users
   guestbookContainer.style.display = "none";
 }
});

測試發送消息

  1. 確保您已登錄該應用程序。
  2. 輸入諸如“ Hey there!”的消息,然後單擊“ SEND”

該操作會將消息寫入您的Cloud Firestore數據庫。但是,由於您仍然需要實現檢索數據,因此您尚未在實際的Web應用中看到該消息。接下來,您將執行此操作。

但是您可以在Firebase控制台中看到新添加的消息。

在Firebase控制台的“數據庫”儀表板中,您應該看到帶有新添加的消息的guestbook集合。如果您繼續發送消息,則您的留言簿集合將包含許多文檔,如下所示:

Firebase控制台

713870af0b3b63c.png

同步消息

訪客可以將消息寫入數據庫,但是他們還無法在應用程序中看到消息,這很可愛。

要顯示消息,您需要添加在數據更改時觸發的偵聽器,然後創建一個顯示新消息的UI元素。

您將添加用於偵聽來自該應用程序的新添加消息的代碼。首先,在HTML中添加一個部分以顯示消息:

  1. 在StackBlitz中,轉到index.html文件。
  2. guestbook-container ,添加一個ID為guestbook的新部分。
<!-- ... -->

  <section id="guestbook-container">
   <h2>Discussion</h2>

   <form><!-- ... --></form>

   <section id="guestbook"></section>

 </section>

<!-- ... -->

接下來,註冊用於偵聽對數據所做的更改的偵聽器:

  1. 在StackBlitz中,轉到index.js文件。
  2. 在文件的底部,添加以下代碼以遍歷數據庫中的所有文檔(來賓留言):
// ...
// Create query for messages
firebase.firestore().collection("guestbook")
.orderBy("timestamp","desc")
.onSnapshot((snaps) => {
 // Reset page
 guestbook.innerHTML = "";
 // Loop through documents in database
 snaps.forEach((doc) => {
   // Create an HTML entry for each document and add it to the chat
   const entry = document.createElement("p");
   entry.textContent = doc.data().name + ": " + doc.data().text;
   guestbook.appendChild(entry);
 });
});

若要偵聽數據庫中的消息,請使用.collection函數在特定集合上創建查詢。上面的代碼偵聽guestbook集合中的更改,該集合是聊天消息的存儲位置。消息也按日期排序,使用.orderBy('timestamp', 'desc')在頂部顯示最新消息。

.onSnapshot函數採用一個參數:回調函數。當與查詢匹配的文檔發生任何更改時,都會觸發回調函數。這可能是消息被刪除,修改或添加的情況。有關更多信息,請參閱Cloud Firestore文檔

測試同步消息

Cloud Firestore會自動並立即將數據與預訂數據庫的客戶端同步。

  1. 您先前在數據庫中創建的消息應顯示在應用程序中。隨時編寫新消息;它們應該立即出現。
  2. 如果您在多個窗口或選項卡中打開工作區,則消息將在選項卡之間實時同步。
  3. (可選)您可以嘗試直接在Firebase控制台的“數據庫”部分中手動刪除,修改或添加新消息。任何更改都應出現在用戶界面中。

恭喜你!您正在閱讀應用程序中的Cloud Firestore文檔!

App p評論

e30df0a9614bae7d.png

最初,您將Cloud Firestore設置為使用測試模式,這意味著您的數據庫處於打開狀態,可以進行讀取和寫入。但是,僅應在開發的早期階段使用測試模式。最佳做法是,在開發應用程序時,應為數據庫設置安全規則。安全性應該是您應用程序的結構和行為不可或缺的一部分。

安全規則允許您控制對數據庫中文檔和集合的訪問。靈活的規則語法允許您創建規則,以匹配從對整個數據庫的所有寫入到對特定文檔的操作之間的任何匹配。

您可以在Firebase控制台中編寫Cloud Firestore的安全規則:

  1. 在Firebase控制台的“開發”部分中,單擊“數據庫” ,然後選擇“規則”選項卡(或單擊此處直接轉到“規則”選項卡)。
  2. 您應該看到以下默認安全規則,以及有關該規則已公開的警告。

7767a2d2e64e7275.png

識別收藏

首先,確定應用程序向其寫入數據的集合。

match /databases/{database}/documents ,標識要保護的集合:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
     // You'll add rules here in the next step.
  }
}

添加安全規則

因為您在每個留言簿文檔中都使用了身份驗證UID作為字段,所以您可以獲得身份驗證UID並驗證嘗試寫入文檔的任何人都具有匹配的身份驗證UID。

將讀寫規則添加到您的規則集中,如下所示:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow create:
        if request.auth.uid == request.resource.data.userId;
    }
  }
}

現在,對於留言簿,只有登錄的用戶可以閱讀消息(任何消息!),但是您只能使用用戶ID創建消息。我們也不允許編輯或刪除郵件。

添加驗證規則

添加數據驗證以確保文檔中存在所有預期字段:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow create:
      if request.auth.uid == request.resource.data.userId
          && "name" in request.resource.data
          && "text" in request.resource.data
          && "timestamp" in request.resource.data;
    }
  }
}

重置監聽器

由於您的應用程序現在僅允許經過身份驗證的用戶登錄,因此您應在“身份驗證”偵聽器內移動訪客firestore查詢。否則,將發生權限錯誤,並且用戶註銷後該應用將被斷開連接。

  1. 將guestbook集合的onSnapshot偵聽器拉入一個名為subscribeGuestbook的新函數中。另外,將onSnapshot函數的結果分配給guestbookListener變量。

Firestore onSnapshot偵聽器返回一個取消訂閱功能,您稍後可以使用該功能取消快照偵聽器。

// ...
// Listen to guestbook updates
function subscribeGuestbook(){
   // Create query for messages
 guestbookListener = firebase.firestore().collection("guestbook")
 .orderBy("timestamp","desc")
 .onSnapshot((snaps) => {
   // Reset page
   guestbook.innerHTML = "";
   // Loop through documents in database
   snaps.forEach((doc) => {
     // Create an HTML entry for each document and add it to the chat
     const entry = document.createElement("p");
     entry.textContent = doc.data().name + ": " + doc.data().text;
     guestbook.appendChild(entry);
   });
 });
};
  1. 在下面添加一個稱為unsubscribeGuestbook的新函數。檢查guestbookListener變量是否不為null,然後調用該函數以取消偵聽器。
// ...
// Unsubscribe from guestbook updates
function unsubscribeGuestbook(){
 if (guestbookListener != null)
 {
   guestbookListener();
   guestbookListener = null;
 }
};
  1. 最後,將新函數添加到onAuthStateChanged回調中(使用以下兩個步驟)。
  2. if (user)的底部添加subscribeGuestbook() if (user)
  3. else語句的底部添加unsubscribeGuestbook()
// ...
firebase.auth().onAuthStateChanged((user) => {
if (user){
  startRsvpButton.textContent = "LOGOUT";
  // Show guestbook to logged-in users
  guestbookContainer.style.display = "block";

  // Subscribe to the guestbook collection
  subscribeGuestbook();
}
else{
  startRsvpButton.textContent = "RSVP";
  // Hide guestbook for non-logged-in users
  guestbookContainer.style.display = "none";

  // Unsubscribe from the guestbook collection
  unsubscribeGuestbook();
}
});

Firebase提供了託管服務來服務您的Web應用程序資產。您可以使用Firebase命令行界面(CLI)將文件和託管配置部署到Firebase託管。但是對於此代碼實驗室,您使用的是StackBlitz ,它已將Firebase CLI集成到其工作區中!

您可以使用StackBlitz的Firebase集成來告訴StackBlitz您要將資產部署到哪個Firebase項目:

  1. 如果尚未在StackBlitz中使用GitHub登錄,請單擊右上角的登錄,然後輸入GitHub帳戶憑據。

99a41778bb3c194c.png

  • 如果您已經擁有GitHub帳戶,請使用您的GitHub帳戶登錄。
  • 如果您還沒有GitHub帳戶,請使用用於登錄Firebase的電子郵件地址創建一個GitHub帳戶。
  1. 現在,左側面板中應該有一個Firebase圖標。

2981c2e3ad13c2c1.png 3.點擊登錄到Google 。使用與登錄Firebase相同的電子郵件地址登錄。 4.從Firebase項目列表中,選擇Firebase-Web-Codelab項目。

使用StackBlitz部署到Firebase託管實際上是一鍵式操作:

  1. 在StackBlitz工作區中,單擊頁面左側的Deploy 。是的,就是這樣。一步! 8fe6c0bfc04c8935.png

請訪問文檔以了解有關Firebase託管工作原理的更多信息。

轉到項目的Firebase控制台“主機”部分,以查看有用的主機信息和工具,包括部署的歷史記錄,回滾到應用程序早期版本的功能以及用於設置自定義域的工作流。

記錄與會者的RSVP狀態

現在,您的應用僅允許人們對事件感興趣的人開始聊天。另外,您知道某人是否要來的唯一方法是將其張貼在聊天中。讓我們組織起來,讓人們知道有多少人會來。

您將添加一個切換開關,以註冊想要參加該活動的人員,然後收集即將到來的人數的計數。

  1. 在StackBlitz中,轉到index.html文件。
  2. guestbook-container ,添加一組YESNO按鈕,如下所示:
<!-- ... -->
  <section id="guestbook-container">
   <h2>Are you attending?</h2>
     <button id="rsvp-yes">YES</button>
     <button id="rsvp-no">NO</button>

   <h2>Discussion</h2>

   <!-- ... -->

 </section>
<!-- ... -->

應用預覽

73ca99ca35c13ee7.png

接下來,為按鈕單擊註冊偵聽器。如果用戶單擊YES ,則使用其身份驗證UID將響應保存到數據庫。

  1. 在StackBlitz中,轉到index.js文件。
  2. 在文件的底部,添加以下代碼以偵聽RSVP狀態:
// ...

// Listen to RSVP responses
rsvpYes.onclick = () => {
}
rsvpNo.onclick = () => {
}
  1. 創建一個名為attendees的新集合,如果單擊任一RSVP按鈕,則註冊文檔參考。
  2. 根據單擊哪個按鈕,將該引用設置為truefalse

首先,對於rsvpYes

// ...

// Listen to RSVP responses
rsvpYes.onclick = () => {
 // Get a reference to the user's document in the attendees collection
 const userDoc = firebase.firestore().collection('attendees').doc(firebase.auth().currentUser.uid);

 // If they RSVP'd yes, save a document with attending: true
 userDoc.set({
   attending: true
 }).catch(console.error)
}

然後,對於rsvpNo相同,但值為false

rsvpNo.onclick = () => {
 // Get a reference to the user's document in the attendees collection
 const userDoc = firebase.firestore().collection('attendees').doc(firebase.auth().currentUser.uid);

 // If they RSVP'd no, save a document with attending: false
 userDoc.set({
   attending: false
 }).catch(console.error)
}

添加規則

因為您已經設置了一些規則,所以將拒絕您使用按鈕添加的新數據。您需要更新規則以允許添加到attendees集合中。

對於attendees集合,由於您使用了身份驗證UID作為文檔名稱,因此您可以抓取它並驗證提交者的uid與他們正在編寫的文檔相同。您將允許所有人閱讀參與者列表(因為那裡沒有私人數據),但是只有創建者才可以更新它。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }
  }
}

添加驗證規則

添加數據驗證以確保文檔中存在所有預期字段:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId
          && "attending" in request.resource.data;

    }
  }
}

(可選)您現在可以查看單擊按鈕的結果。在Firebase控制台中轉到Cloud Firestore儀表板。

讀取RSVP狀態

現在,您已經記錄了響應,讓我們看看誰來了,並將其反映在UI中。

  1. 在StackBlitz中,轉到index.html文件。
  2. description-container ,添加一個ID為number-attending的新元素。
<!-- ... -->

 <section id="description-container">
     <!-- ... -->
     <p id="number-attending"></p>
 </section>

<!-- ... -->

接下來,為attendees集合註冊偵聽器,併計算“是響應的數量:

  1. 在StackBlitz中,轉到index.js文件。
  2. 在文件底部,添加以下代碼以偵聽RSVP狀態併計數YES單擊。
// ...
// Listen for attendee list
firebase.firestore()
.collection('attendees')
.where("attending", "==", true)
.onSnapshot(snap => {
 const newAttendeeCount = snap.docs.length;

 numberAttending.innerHTML = newAttendeeCount+' people going'; 
})
  1. 最後,讓我們突出顯示與當前狀態相對應的按鈕。檢查當前身份驗證UID在attendees集合中是否有條目,然後將類設置為clicked
// ...
// Listen for attendee list
function subscribeCurrentRSVP(user){
 rsvpListener = firebase.firestore()
 .collection('attendees')
 .doc(user.uid)
 .onSnapshot((doc) => {
   if (doc && doc.data()){
     const attendingResponse = doc.data().attending;

     // Update css classes for buttons
     if (attendingResponse){
       rsvpYes.className="clicked";
       rsvpNo.className="";
     }
     else{
       rsvpYes.className="";
       rsvpNo.className="clicked";
     }
   }
 });
}
  1. 另外,讓我們取消訂閱功能。用戶註銷時將使用它。
第094章
  1. 從身份驗證偵聽器調用函數。
// ...

// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user) => {
if (user){
  startRsvpButton.textContent = "LOGOUT";
  // Show guestbook to logged-in users
  guestbookContainer.style.display = "block";

  // Subscribe to the guestbook collection
  subscribeGuestbook();
  // Subscribe to the guestbook collection
  subscribeCurrentRSVP(user);
}
else{
  startRsvpButton.textContent = "RSVP";
  // Hide guestbook for non-logged-in users
  guestbookContainer.style.display = "none";

  // Unsubscribe from the guestbook collection
  unsubscribeGuestbook();
  // Unsubscribe from the guestbook collection
  unsubscribeCurrentRSVP();

}
});
  1. 嘗試以多個用戶身份登錄,並且每單擊一次YES按鈕,就會看到計數增加。

應用預覽

3df607d3e0b3c35.png

您已經使用Firebase構建了交互式的實時Web應用程序!

我們涵蓋的內容

  • Firebase身份驗證
  • FirebaseUI
  • Cloud Firestore
  • Firebase安全規則
  • Firebase託管

下一步

了解更多

怎麼樣了

我們希望收到您的反饋!請在此處填寫(非常)簡短的表格。