Google 致力于为黑人社区推动种族平等。查看具体举措
此页面由 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 * as 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 App注册该应用程序
  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. 拉留言收集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. 另外,让我们取消订阅功能。用户注销时将使用它。
// ...

function unsubscribeCurrentRSVP(){
 if (rsvpListener != null)
 {
   rsvpListener();
   rsvpListener = null;
 }
 rsvpYes.className="";
 rsvpNo.className="";
}
  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托管

下一步

了解更多

怎么样了

我们希望收到您的反馈!请在此处填写(非常)简短的表格。