Google 致力于为黑人社区推动种族平等。查看具体举措

Firebase 网络代码实验室

在此 Codelab 中,您将学习如何使用Firebase通过使用 Firebase 产品和服务实现和部署聊天客户端来轻松创建 Web 应用程序。

3b1284f5144b54f6.png

你会学到什么

  • 使用 Cloud Firestore 和 Cloud Storage for Firebase 同步数据。
  • 使用 Firebase 身份验证对您的用户进行身份验证。
  • 在 Firebase 托管上部署您的网络应用。
  • 使用 Firebase 云消息传递发送通知。
  • 收集您的网络应用程序的性能数据。

你需要什么

  • 您选择的 IDE/文本编辑器,例如WebStormAtomSublimeVS Code
  • 包管理器npm ,通常与Node.js 一起提供
  • 一个终端/控制台
  • 您选择的浏览器,例如 Chrome
  • codelab的示例代码(获取代码的方法见codelab下一步)

从命令行克隆 codelab 的GitHub 存储库

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

或者,如果您没有安装 git,您可以 将存储库下载为 ZIP 文件

导入入门应用

使用您的 IDE,从克隆的存储库中打开或导入 📁 web-start目录。这个 📁 web-start目录包含 codelab 的起始代码,它将是一个功能齐全的聊天网络应用程序。

创建 Firebase 项目

  1. 登录Firebase
  2. 在 Firebase 控制台中,点击Add Project ,然后将您的 Firebase 项目命名为FriendlyChat 。记住您的 Firebase 项目的项目 ID。
  3. 取消选中为此项目启用 Google Analytics
  4. 单击创建项目

我们将要构建的应用程序使用可用于网络应用程序的 Firebase 产品:

  • Firebase 身份验证可让您的用户轻松登录您的应用。
  • Cloud Firestore将结构化数据保存在云端,并在数据发生变化时获得即时通知。
  • 用于 Firebase 的 Cloud Storage,用于将文件保存在云中。
  • Firebase 托管来托管和服务您的资产。
  • Firebase Cloud Messaging发送推送通知和显示浏览器弹出通知。
  • Firebase 性能监控,用于为您的应用收集用户性能数据。

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

将 Firebase 网络应用添加到项目

  1. 单击网络图标58d6543a156e56f9.png创建一个新的 Firebase 网络应用。
  2. 使用昵称Friendly Chat注册该应用程序,然后选中还为此应用程序设置 Firebase 托管旁边的框。点击注册应用程序
  3. 单击剩余的步骤。您现在不需要按照说明进行操作;这些将在本 Codelab 的后续步骤中介绍。

ea9ab0db531a104c.png

为 Firebase 身份验证启用 Google登录

为了允许用户使用他们的 Google 帐户登录网络应用程序,我们将使用Google登录方法。

您需要启用Google登录:

  1. 在 Firebase 控制台中,找到左侧面板中的Build部分。
  2. 单击“身份验证” ,然后单击“登录方法”选项卡(或单击此处直接转到此处)。
  3. 启用Google登录提供程序,然后点击保存
  4. 将您的应用面向公众的名称设置为“友好聊天”然后从下拉菜单中选择项目支持电子邮件
  5. Google Cloud Console 中配置您的 OAuth 同意屏幕并添加徽标:

d89fb3873b5d36ae.png

启用 Cloud Firestore

该网络应用使用Cloud Firestore保存聊天消息并接收新的聊天消息。

您需要启用 Cloud Firestore:

  1. 在 Firebase 控制台的Build部分,点击Firestore Database
  2. 单击 Cloud Firestore 窗格中的创建数据库

729991a081e7cd5.png

  1. 选择以测试模式启动选项,然后在阅读有关安全规则的免责声明后单击下一步

测试模式确保我们在开发过程中可以自由写入数据库。我们稍后将在此代码实验室中使我们的数据库更加安全。

77e4986cbeaf9dee.png

  1. 设置您的 Cloud Firestore 数据的存储位置。您可以将其保留为默认值或选择离您最近的区域。单击“完成”以配置 Firestore。

9f2bb0d4e7ca49c7.png

启用云存储

该网络应用使用 Cloud Storage for Firebase 来存储、上传和共享图片。

您需要启用云存储:

  1. 在 Firebase 控制台的Build部分,点击Storage
  2. 如果没有“开始”按钮,则表示云存储已启用,您无需执行以下步骤。
  3. 单击开始
  4. 阅读有关 Firebase 项目安全规则的免责声明,然后点击Next

使用默认安全规则,任何经过身份验证的用户都可以向 Cloud Storage 写入任何内容。我们稍后将在此 Codelab 中使我们的存储更加安全。

62f1afdcd1260127.png

  1. Cloud Storage 位置与您为 Cloud Firestore 数据库选择的区域相同。单击完成以完成设置。

1d7f49ebaddb32fc.png

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

我们已经设置了网络应用模板,以从应用的本地目录(您之前在 codelab 中克隆的存储库)中提取应用的 Firebase 托管配置。但是要提取配置,我们需要将您的应用与您的 Firebase 项目相关联。

  1. 确保您的命令行正在访问您的应用程序的本地web-start目录。
  2. 通过运行以下命令将您的应用与 Firebase 项目相关联:
firebase use --add
  1. 出现提示时,选择您的项目 ID ,然后为您的 Firebase 项目指定一个别名。

如果您有多个环境(生产、暂存等),则别名很有用。但是,对于这个代码实验室,我们只使用default的别名。

  1. 按照命令行上的其余说明进行操作。

现在您已经导入并配置了您的项目,您已准备好第一次运行 Web 应用程序。

  1. web-start目录的控制台中,运行以下 Firebase CLI 命令:
firebase serve --only hosting
  1. 您的命令行应显示以下响应:
✔  hosting: Local server: http://localhost:5000

我们正在使用Firebase 托管模拟器在本地为我们的应用提供服务。现在应该可以从http://localhost:5000访问 Web 应用程序。提供位于public子目录下的所有文件。

  1. 使用您的浏览器,在http://localhost:5000打开您的应用程序。

您应该会看到您的 FriendlyChat 应用程序的用户界面,它(尚未!)运行:

4c23f9475228cef4.png

该应用程序现在无法执行任何操作,但在您的帮助下它很快就会执行!到目前为止,我们只为您布置了 UI。

现在让我们建立一个实时聊天!

导入 Firebase SDK

我们需要将 Firebase SDK 导入应用程序。如我们的文档中所述,有多种方法可以执行此操作。例如,您可以从我们的 CDN 导入库。或者你可以使用 npm 在本地安装它,如果你使用 Browserify,然后将它打包到你的应用程序中。

由于我们使用 Firebase 托管来为我们的应用提供服务,因此我们将导入文件index.html (位于您的web-start/public/目录中)中的本地 URL。对于这个代码实验室,我们已经在index.html文件的底部为您添加了以下几行,但您可以仔细检查它们是否在那里。

索引.html

<script src="/__/firebase/8.6.7/firebase-app.js"></script>
<script src="/__/firebase/8.6.7/firebase-auth.js"></script>
<script src="/__/firebase/8.6.7/firebase-storage.js"></script>
<script src="/__/firebase/8.6.7/firebase-messaging.js"></script>
<script src="/__/firebase/8.6.7/firebase-firestore.js"></script>
<script src="/__/firebase/8.6.7/firebase-performance.js"></script>

在此 Codelab 中,我们将使用 Firebase Authentication、Cloud Firestore、Cloud Storage、Cloud Messaging 和 Performance Monitoring,因此我们将导入它们的所有库。在您未来的应用中,请确保您只导入您需要的 Firebase 部分,以缩短应用的加载时间。

配置 Firebase

我们还需要配置 Firebase SDK 以告诉它我们正在使用哪个 Firebase 项目。由于我们使用的是 Firebase 托管,您可以导入一个特殊的脚本来为您执行此配置。同样,对于这个代码实验室,我们已经在public/index.html文件的底部为您添加了以下行,但请仔细检查它是否在那里。

索引.html

<script src="/__/firebase/init.js"></script>

此脚本包含基于您之前在运行firebase use --add时指定的 Firebase 项目的 Firebase 项目配置。

随意检查文件init.js以查看您的项目配置是什么样的。为此,请在浏览器中打开http://localhost:5000/__/firebase/init.js 。您应该会看到如下所示的内容:

/__/firebase/init.js

if (typeof firebase === 'undefined') throw new Error('hosting/init-error: Firebase SDK not detected. You must include it before /__/firebase/init.js');
firebase.initializeApp({
  "apiKey": "qwertyuiop_asdfghjklzxcvbnm1234568_90",
  "databaseURL": "https://friendlychat-1234.firebaseio.com",
  "storageBucket": "friendlychat-1234.appspot.com",
  "authDomain": "friendlychat-1234.firebaseapp.com",
  "messagingSenderId": "1234567890",
  "projectId": "friendlychat-1234",
  "appId": "1:1234567890:web:123456abcdef"
});

Firebase SDK 现在应该可以使用了,因为它已在index.html导入和初始化。我们现在将使用Firebase 身份验证实现用户登录。

使用 Google Sign-In 对您的用户进行身份验证

在应用程序中,当用户单击“使用 Google 登录”按钮时,会触发signIn功能。 (我们已经为您设置好了!)对于此代码实验室,我们希望授权 Firebase 使用 Google 作为身份提供者。我们将使用弹出窗口,但 Firebase 还提供其他几种方法

  1. web-start目录的子目录public/scripts/ ,打开main.js
  2. 找到函数signIn
  3. 用以下代码替换整个函数。

主文件

// Signs-in Friendly Chat.
function signIn() {
  // Sign into Firebase using popup auth & Google as the identity provider.
  var provider = new firebase.auth.GoogleAuthProvider();
  firebase.auth().signInWithPopup(provider);
}

signOut当用户点击退出按钮功能被触发。

  1. 返回文件public/scripts/main.js
  2. 找到函数signOut
  3. 用以下代码替换整个函数。

主文件

// Signs-out of Friendly Chat.
function signOut() {
  // Sign out of Firebase.
  firebase.auth().signOut();
}

跟踪认证状态

为了相应地更新我们的 UI,我们需要一种方法来检查用户是登录还是退出。使用 Firebase 身份验证,您可以在每次身份验证状态更改时触发的身份验证状态上注册观察者。

  1. 返回文件public/scripts/main.js
  2. 找到函数initFirebaseAuth
  3. 用以下代码替换整个函数。

主文件

// Initiate Firebase Auth.
function initFirebaseAuth() {
  // Listen to auth state changes.
  firebase.auth().onAuthStateChanged(authStateObserver);
}

上面的代码将函数authStateObserver注册为身份验证状态观察器。每次身份验证状态更改时(用户登录或退出时)都会触发它。此时,我们将更新 UI 以显示或隐藏登录按钮、注销按钮、登录用户的个人资料图片等。所有这些 UI 部分都已经实现。

显示登录用户的信息

我们希望在应用程序的顶部栏中显示登录用户的个人资料图片和用户名。在 Firebase 中,登录用户的数据始终在firebase.auth().currentUser对象中可用。之前,我们设置了authStateObserver函数以在用户authStateObserver时触发,以便我们的 UI 相应地更新。它会在触发时调用getProfilePicUrlgetUserName

  1. 返回文件public/scripts/main.js
  2. 找到函数getProfilePicUrlgetUserName
  3. 用以下代码替换这两个函数。

主文件

// Returns the signed-in user's profile pic URL.
function getProfilePicUrl() {
  return firebase.auth().currentUser.photoURL || '/images/profile_placeholder.png';
}

// Returns the signed-in user's display name.
function getUserName() {
  return firebase.auth().currentUser.displayName;
}

如果用户在未登录时尝试发送消息,我们会显示一条错误消息。(不过您可以尝试!)因此,我们需要检测用户是否实际登录。

  1. 返回文件public/scripts/main.js
  2. 找到函数isUserSignedIn
  3. 用以下代码替换整个函数。

主文件

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!firebase.auth().currentUser;
}

测试登录应用

  1. 如果您的应用仍在提供服务,请在浏览器中刷新您的应用。否则,在命令行上运行firebase serve --only hosting以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。
  2. 使用登录按钮和您的 Google 帐户登录应用程序。如果您看到一条错误消息,指出auth/operation-not-allowed ,请检查以确保您在 Firebase 控制台中将 Google 登录作为身份验证提供程序启用。
  3. 登录后,应显示您的个人资料图片和用户名: c7401b3d44d0d78b.png

在本节中,我们将向 Cloud Firestore 写入一些数据,以便我们可以填充应用的 UI。这可以通过Firebase 控制台手动完成,但我们将在应用程序中完成,以演示基本的 Cloud Firestore 写入。

数据模型

Cloud Firestore 数据分为集合、文档、字段和子集合。我们将聊天的每条消息作为文档存储在名为messages的顶级集合中。

688d7bc5fb662b57.png

将消息添加到 Cloud Firestore

为了存储用户编写的聊天消息,我们将使用Cloud Firestore

在本节中,您将添加用户将新消息写入数据库的功能。用户单击SEND按钮将触发下面的代码片段。它将带有消息字段内容的消息对象添加到messages集合中的 Cloud Firestore 实例。 add()方法将一个带有自动生成的 ID 的新文档添加到集合中。

  1. 返回文件public/scripts/main.js
  2. 找到函数saveMessage
  3. 用以下代码替换整个函数。

主文件

// Saves a new message to your Cloud Firestore database.
function saveMessage(messageText) {
  // Add a new message entry to the database.
  return firebase.firestore().collection('messages').add({
    name: getUserName(),
    text: messageText,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).catch(function(error) {
    console.error('Error writing new message to database', error);
  });
}

测试发送消息

  1. 如果您的应用仍在提供服务,请在浏览器中刷新您的应用。否则,在命令行上运行firebase serve --only hosting以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。
  2. 登录后,输入诸如“Hey there!”之类的消息,然后单击“发送” 。这会将消息写入 Cloud Firestore。但是,您还不会在实际的 Web 应用程序中看到数据,因为我们仍然需要实现检索数据(代码实验室的下一部分)。
  3. 您可以在 Firebase 控制台中看到新添加的消息。打开您的 Firebase 控制台。在Build部分下单击Database (或单击此处并选择您的项目),您应该会看到带有新添加消息的消息集合:

6812efe7da395692.png

同步消息

要在应用程序中读取消息,我们需要添加在数据更改时触发的侦听器,然后创建一个显示新消息的 UI 元素。

我们将添加用于侦听来自应用程序的新添加消息的代码。在此代码中,我们将注册侦听数据更改的侦听器。我们将只显示聊天的最后 12 条消息,以避免在加载时显示很长的历史记录。

  1. 返回文件public/scripts/main.js
  2. 找到函数loadMessages
  3. 用以下代码替换整个函数。

主文件

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  var query = firebase.firestore()
                  .collection('messages')
                  .orderBy('timestamp', 'desc')
                  .limit(12);
  
  // Start listening to the query.
  query.onSnapshot(function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                       message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

为了侦听数据库中的消息,我们通过使用.collection函数来创建一个对集合的查询,以指定我们想要侦听的数据在哪个集合中。在上面的代码中,我们正在侦听messages集合,这是存储聊天消息的地方。我们还通过仅使用.limit(12)侦听最后 12 条消息并使用.orderBy('timestamp', 'desc')按日期对消息进行排序来应用限制以获取 12 条最新消息。

.onSnapshot函数接受一个参数:回调函数。当与查询匹配的文档有任何更改时,将触发回调函数。这可能是因为消息被删除、修改或添加。您可以在Cloud Firestore 文档 中阅读有关此内容的更多信息。

测试同步消息

  1. 如果您的应用仍在提供服务,请在浏览器中刷新您的应用。否则,在命令行上运行firebase serve --only hosting以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。
  2. 您之前在数据库中创建的消息应显示在 FriendlyChat UI 中(见下文)。随意编写新消息;他们应该立即出现。
  3. (可选)您可以尝试直接在 Firebase 控制台的数据库部分中手动删除、修改或添加新消息;任何更改都应反映在 UI 中。

恭喜!您正在您的应用中阅读 Cloud Firestore 文档!

2168dec79b573d07.png

我们现在将添加一个共享图像的功能。

Cloud Firestore 适合存储结构化数据,而 Cloud Storage 更适合存储文件。 Cloud Storage for Firebase是一种文件/blob 存储服务,我们将使用它来存储用户使用我们的应用共享的任何图像。

将图像保存到云存储

对于此代码实验室,我们已经为您添加了一个触发文件选择器对话框的按钮。选择文件后,调用saveImageMessage函数,您可以获得对所选文件的引用。 saveImageMessage函数完成以下操作:

  1. 在聊天提要中创建“占位符”聊天消息,以便用户在我们上传图像时看到“加载”动画。
  2. 将图像文件上传到 Cloud Storage 到此路径: /<uid>/<messageId>/<file_name>
  3. 为图像文件生成一个公开可读的 URL。
  4. 使用新上传的图像文件的 URL 代替临时加载的图像更新聊天消息。

现在您将添加发送图像的功能:

  1. 返回文件public/scripts/main.js
  2. 找到函数saveImageMessage
  3. 用以下代码替换整个函数。

主文件

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
function saveImageMessage(file) {
  // 1 - We add a message with a loading icon that will get updated with the shared image.
  firebase.firestore().collection('messages').add({
    name: getUserName(),
    imageUrl: LOADING_IMAGE_URL,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).then(function(messageRef) {
    // 2 - Upload the image to Cloud Storage.
    var filePath = firebase.auth().currentUser.uid + '/' + messageRef.id + '/' + file.name;
    return firebase.storage().ref(filePath).put(file).then(function(fileSnapshot) {
      // 3 - Generate a public URL for the file.
      return fileSnapshot.ref.getDownloadURL().then((url) => {
        // 4 - Update the chat message placeholder with the image's URL.
        return messageRef.update({
          imageUrl: url,
          storageUri: fileSnapshot.metadata.fullPath
        });
      });
    });
  }).catch(function(error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  });
}

测试发送图片

  1. 如果您的应用仍在提供服务,请在浏览器中刷新您的应用。否则,在命令行上运行firebase serve --only hosting以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。
  2. 登录后,点击图片上传按钮13734cb66773e5a3.png并使用文件选择器选择一个图像文件。如果您正在寻找图片,请随意使用这张精美的咖啡杯图片
  3. 应用程序的 UI 中应该会出现一条带有您选择的图像的新消息: 3b1284f5144b54f6.png

如果您在未登录的情况下尝试添加图像,您应该会看到 Toast 通知,告诉您必须登录才能添加图像。

我们现在将添加对浏览器通知的支持。该应用程序将在聊天中发布新消息时通知用户。 Firebase 云消息传递(FCM) 是一种跨平台消息传递解决方案,可让您可靠地免费传递消息和通知。

将 GCM 发件人 ID 列入白名单

Web 应用清单中,您需要指定gcm_sender_id ,这是一个硬编码值,表示 FCM 有权向此应用发送消息。

  1. web-start目录的public目录中,打开manifest.json
  2. gcm_sender_id属性中添加浏览器发件人 ID 值,如下所示。请勿更改下图所示的值。

清单文件.json

{
  "name": "Friendly Chat",
  "short_name": "Friendly Chat",
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "portrait",
  "gcm_sender_id": "103953800507"
}

添加 FCM 服务工作者

Web 应用程序需要一个Service Worker来接收和显示 Web 通知。

  1. web-start目录的public目录中,创建一个名为firebase-messaging-sw.js的新文件。
  2. 将以下内容添加到该新文件中。

firebase-messaging-sw.js

importScripts('/__/firebase/6.0.4/firebase-app.js');
importScripts('/__/firebase/6.0.4/firebase-messaging.js');
importScripts('/__/firebase/init.js');

firebase.messaging();

Service Worker 只需要加载和初始化 Firebase Cloud Messaging SDK,它将负责显示通知。

获取 FCM 设备令牌

在设备或浏览器上启用通知后,您将获得一个设备令牌。我们使用此设备令牌向特定设备或特定浏览器发送通知。

当用户saveMessagingDeviceToken ,我们调用saveMessagingDeviceToken函数。这就是我们将从浏览器获取FCM 设备令牌并将其保存到 Cloud Firestore 的地方。

  1. 返回文件public/scripts/main.js
  2. 找到函数saveMessagingDeviceToken
  3. 用以下代码替换整个函数。

主文件

// Saves the messaging device token to the datastore.
function saveMessagingDeviceToken() {
  firebase.messaging().getToken().then(function(currentToken) {
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to the datastore.
      firebase.firestore().collection('fcmTokens').doc(currentToken)
          .set({uid: firebase.auth().currentUser.uid});
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  }).catch(function(error){
    console.error('Unable to get messaging token.', error);
  });
}

但是,此代码最初不起作用。为了让您的应用能够检索设备令牌,用户需要授予您的应用显示通知的权限(代码实验室的下一步)。

请求显示通知的权限

如果用户尚未授予您的应用显示通知的权限,您将不会获得设备令牌。在这种情况下,我们调用firebase.messaging().requestPermission()方法,该方法将显示一个请求此权限的浏览器对话框(在支持的浏览器中)。

8b9d0c66dc36153d.png

  1. 返回文件public/scripts/main.js
  2. 找到函数requestNotificationsPermissions
  3. 用以下代码替换整个函数。

主文件

// Requests permission to show notifications.
function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  firebase.messaging().requestPermission().then(function() {
    // Notification permission granted.
    saveMessagingDeviceToken();
  }).catch(function(error) {
    console.error('Unable to get permission to notify.', error);
  });
}

获取您的设备令牌

  1. 如果您的应用仍在提供服务,请在浏览器中刷新您的应用。否则,在命令行上运行firebase serve --only hosting以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。
  2. 登录后,通知权限对话框应出现: bd3454e6dbfb6723.png
  3. 单击“允许”
  4. 打开浏览器的 JavaScript 控制台。您应该会看到以下消息: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. 复制您的设备令牌。您将在代码实验室的下一阶段需要它。

向您的设备发送通知

现在您拥有设备令牌,您可以发送通知。

  1. 除了设备令牌,您还需要 Firebase 应用的Server Key 。要获取此密钥,请转到Firebase Console > Project Settings > Cloud Messaging ,然后复制Server Key

要发送通知,您需要发送以下 HTTP 请求:

POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=YOUR_SERVER_KEY

{
  "notification": {
    "title": "New chat message!",
    "body": "There is a new message in FriendlyChat",
    "icon": "/images/profile_placeholder.png",
    "click_action": "http://localhost:5000"
  },
  "to":"YOUR_DEVICE_TOKEN"
}
  1. 在命令行上,运行以下cURL命令。
curl -H "Content-Type: application/json" \
     -H "Authorization: key=YOUR_SERVER_KEY" \
     -d '{
           "notification": {
             "title": "New chat message!",
             "body": "There is a new message in FriendlyChat",
             "icon": "/images/profile_placeholder.png",
             "click_action": "http://localhost:5000"
           },
           "to": "YOUR_DEVICE_TOKEN"
         }' \
     https://fcm.googleapis.com/fcm/send

请注意,只有当 FriendlyChat 应用程序在后台时才会显示通知。您必须离开或显示另一个选项卡才能显示通知。当应用程序在前台时,有一种方法可以捕获 FCM 发送的消息

如果您的应用程序在后台运行,则浏览器中应显示通知,如下例所示:

de79e8638a45864c.png

查看数据库安全规则

Cloud Firestore 使用特定的规则语言来定义访问权限、安全性和数据验证。

在本 Codelab 开始时设置 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;
    }
  }
}

更新数据库安全规则

有两种方法可以编辑数据库安全规则,在 Firebase 控制台中或从使用 Firebase CLI 部署的本地规则文件中。

要在 Firebase 控制台中更新安全规则:

  1. 从左侧面板转到数据库部分,然后单击规则选项卡。
  2. 将控制台中已有的默认规则替换为上面显示的规则。
  3. 单击发布

从本地文件更新安全规则:

  1. web-start目录中,打开firestore.rules
  2. 用上面显示的规则替换文件中已有的默认规则。
  3. web-start目录中,打开firebase.json
  4. 添加指向firestore.rulesfirestore.rules属性,如下所示。 ( hosting属性应该已经在文件中。)

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. 通过运行以下命令,使用 Firebase CLI 部署安全规则:
firebase deploy --only firestore
  1. 您的命令行应显示以下响应:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

查看 Cloud Storage 安全规则

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

更新 Cloud Storage 安全规则

有两种方法可以编辑存储安全规则:在 Firebase 控制台中或从使用 Firebase CLI 部署的本地规则文件中。

要在 Firebase 控制台中更新安全规则:

  1. 从左侧面板转到存储部分,然后单击规则选项卡。
  2. 将控制台中已有的默认规则替换为上面显示的规则。
  3. 单击发布

从本地文件更新安全规则:

  1. web-start目录中,打开storage.rules
  2. 用上面显示的规则替换文件中已有的默认规则。
  3. web-start目录中,打开firebase.json
  4. 添加指向storage.rules文件的storage.rules属性,如下所示。 ( hostingdatabase属性应该已经在文件中。)

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // Add this!
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. 通过运行以下命令,使用 Firebase CLI 部署安全规则:
firebase deploy --only storage
  1. 您的命令行应显示以下响应:
=== Deploying to 'friendlychat-1234'...

i  deploying storage
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

您可以使用 Performance Monitoring SDK 从您的应用中收集真实世界的性能数据,然后在 Firebase 控制台中查看和分析该数据。性能监控可帮助您了解可以在何时何地改进应用程序的性能,以便您可以使用该信息来解决性能问题。

有多种方法可以与 Firebase 性能监控 JavaScript SDK 集成。在此 Codelab 中,我们启用了来自托管 URL 的性能监控。请参阅文档以查看启用 SDK 的其他方法。

自动跟踪

由于我们在init.js的前面步骤中包含了init.js firebase-performance.jsinit.js ,我们只需要添加一行来告诉性能监控在用户访问您部署的站点时自动为您收集页面负载和网络请求指标!

  1. public/scripts/main.js ,在现有TODO下方添加以下行以初始化性能监控。

主文件

// TODO: Enable Firebase Performance Monitoring.
firebase.performance();

测量首次输入延迟(可选)

首次输入延迟很有用,因为浏览器对用户交互的响应可以让用户对应用的响应能力有第一印象。

当用户第一次与页面上的元素交互时,首次输入延迟开始,比如点击按钮或超链接。它在浏览器能够响应输入后立即停止,这意味着浏览器不会忙于加载或解析您的页面内容。

如果您想测量首次输入延迟,则需要直接包含以下代码。

  1. 打开public/index.html
  2. 取消注释以下行中的script标记。

索引.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

要阅读有关第一个输入延迟 polyfill 的更多信息,请查看文档

查看性能数据

由于您尚未部署您的网站(您将在下一步中部署它),下面的屏幕截图显示了您将在用户与您部署的网站互动 30 分钟内在 Firebase 控制台中看到的页面加载性能指标:

29389131150f33d7.png

当您将性能监控 SDK 集成到您的应用程序中时,您无需编写任何其他代码即可在您的应用程序开始自动监控性能的几个关键方面。对于 Web 应用程序,SDK 会记录诸如首次内容绘制、用户与您的应用程序交互的能力等方面。

您还可以设置自定义跟踪、指标和属性来衡量应用程序的特定方面。访问文档以了解有关自定义跟踪和度量以及自定义属性的更多信息。

Firebase 提供托管服务来为您的资产和网络应用提供服务。您可以使用 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. 确保您的命令行正在访问您的应用程序的本地web-start目录。
  2. Deploy your files to your Firebase project by running the following command:
firebase deploy --except functions
  1. The console should display the following:
=== 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. Visit your web app that's now fully hosted using Firebase Hosting at two of your very own Firebase subdomains:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app .

Alternatively, you can run firebase open hosting:site in the command line.

Visit the documentation to learn more about how Firebase Hosting works .

Go to your project's Firebase console Hosting section to view useful hosting information and tools, including the history of your deploys, the functionality to roll back to previous versions of your app, and the workflow to set up a custom domain.

You've used Firebase to build a real-time chat web application!

What we've covered

  • Firebase Authentication
  • Cloud Firestore
  • Firebase SDK for Cloud Storage
  • Firebase Cloud Messaging
  • Firebase Performance Monitoring
  • Firebase Hosting

Next steps

Learn more