一、概述
在此 Codelab 中,您将学习如何使用Firebase通过使用 Firebase 产品和服务实施和部署聊天客户端来轻松创建 Web 应用程序。
你会学到什么
- 使用 Cloud Firestore 和 Cloud Storage for Firebase 同步数据。
- 使用 Firebase 身份验证对您的用户进行身份验证。
- 在 Firebase 托管上部署您的网络应用。
- 使用 Firebase 云消息传递发送通知。
- 收集您的网络应用程序的性能数据。
你需要什么
2.获取示例代码
从命令行克隆代码实验室的GitHub 存储库:
git clone https://github.com/firebase/codelab-friendlychat-web
或者,如果您没有安装 git,您可以将存储库下载为 ZIP 文件。
导入入门应用
使用您的 IDE,从克隆的存储库中打开或导入 📁 web-start
目录。这个 📁 web-start
目录包含代码实验室的起始代码,这将是一个功能齐全的聊天网络应用程序。
3. 创建并设置一个 Firebase 项目
创建一个 Firebase 项目
- 登录到Firebase 。
- 在 Firebase 控制台中,单击添加项目,然后将您的 Firebase 项目命名为FriendlyChat 。记住您的 Firebase 项目的项目 ID。
- 取消选中为此项目启用 Google Analytics
- 单击创建项目。
我们要构建的应用程序使用可用于网络应用程序的 Firebase 产品:
- Firebase 身份验证可让您的用户轻松登录您的应用。
- Cloud Firestore将结构化数据保存在云端,并在数据发生变化时获得即时通知。
- Cloud Storage for Firebase用于将文件保存在云端。
- Firebase Hosting用于托管和服务您的资产。
- Firebase Cloud Messaging发送推送通知和显示浏览器弹出通知。
- Firebase Performance Monitoring为您的应用收集用户性能数据。
其中一些产品需要特殊配置或需要使用 Firebase 控制台启用。
将 Firebase 网络应用程序添加到项目
- 单击网络图标
创建一个新的 Firebase 网络应用程序。
- 使用昵称Friendly Chat注册应用程序,然后选中Also set up Firebase Hosting for this app旁边的框。单击注册应用程序。
- 在下一步中,您将看到一个配置对象。仅将 JS 对象(而不是周围的 HTML)复制到firebase-config.js
为 Firebase 身份验证启用 Google 登录
为了允许用户使用他们的 Google 帐户登录 Web 应用程序,我们将使用Google登录方法。
您需要启用Google登录:
- 在 Firebase 控制台中,找到左侧面板中的构建部分。
- 单击Authentication ,然后单击Sign-in method选项卡(或单击此处直接转到那里)。
- 启用Google登录提供商,然后点击保存。
- 将您的应用程序的面向公众的名称设置为Friendly Chat ,然后从下拉菜单中选择项目支持电子邮件。
- 在Google Cloud Console中配置您的 OAuth 同意屏幕并添加徽标:
启用 Cloud Firestore
该 Web 应用使用Cloud Firestore保存聊天消息和接收新的聊天消息。
您需要启用 Cloud Firestore:
- 在 Firebase 控制台的构建部分中,单击Firestore 数据库。
- 单击 Cloud Firestore 窗格中的创建数据库。
- 选择Start in test mode选项,然后在阅读有关安全规则的免责声明后单击Next 。
测试模式保证了我们在开发过程中可以自由写入数据库。稍后在此 Codelab 中,我们将使我们的数据库更加安全。
- 设置 Cloud Firestore 数据的存储位置。您可以将其保留为默认值或选择离您较近的区域。单击“完成”以配置 Firestore。
启用云存储
该 Web 应用程序使用 Cloud Storage for Firebase 来存储、上传和共享图片。
您需要启用云存储:
- 在 Firebase 控制台的构建部分中,单击存储。
- 如果没有开始按钮,则表示云存储已经启用,您无需执行以下步骤。
- 单击开始。
- 阅读有关您的 Firebase 项目安全规则的免责声明,然后单击下一步。
使用默认安全规则,任何经过身份验证的用户都可以向 Cloud Storage 写入任何内容。稍后在此 Codelab 中,我们将使我们的存储更加安全。
- 预选的 Cloud Storage 位置与您为 Cloud Firestore 数据库选择的区域相同。单击完成以完成设置。
4.安装Firebase命令行界面
Firebase 命令行界面 (CLI) 允许您使用 Firebase 托管在本地为您的 Web 应用程序提供服务,以及将您的 Web 应用程序部署到您的 Firebase 项目。
- 通过运行以下 npm 命令安装 CLI:
npm -g install firebase-tools
- 通过运行以下命令验证 CLI 是否已正确安装:
firebase --version
确保 Firebase CLI 的版本为 v4.1.0 或更高版本。
- 通过运行以下命令授权 Firebase CLI:
firebase login
我们已经设置了 Web 应用程序模板,以从应用程序的本地目录(您之前在代码实验室中克隆的存储库)中提取应用程序的 Firebase 托管配置。但是要提取配置,我们需要将您的应用程序与您的 Firebase 项目相关联。
- 确保您的命令行正在访问您应用程序的本地
web-start
目录。 - 通过运行以下命令将您的应用与 Firebase 项目相关联:
firebase use --add
- 出现提示时,选择您的Project ID ,然后为您的 Firebase 项目指定一个别名。
如果您有多个环境(生产、暂存等),别名很有用。但是,对于此 Codelab,我们只使用default
的别名。
- 按照命令行上的其余说明进行操作。
5. 在本地运行入门应用
现在您已经导入并配置了您的项目,您已准备好首次运行 Web 应用程序。
- 在
web-start
目录的控制台中,运行以下 Firebase CLI 命令:
firebase serve --only hosting
- 您的命令行应显示以下响应:
✔ hosting: Local server: http://localhost:5000
我们正在使用Firebase 托管模拟器在本地提供我们的应用程序。 Web 应用程序现在应该可以从http://localhost:5000获得。提供位于public
子目录下的所有文件。
- 使用您的浏览器,在http://localhost:5000打开您的应用程序。
您应该会看到您的 FriendlyChat 应用程序的 UI,它(还没有!)正在运行:
该应用程序现在无法执行任何操作,但在您的帮助下它很快就会执行!到目前为止,我们只为您布置了 UI。
现在让我们建立一个实时聊天!
6.导入并配置Firebase
导入 Firebase SDK
我们需要将 Firebase SDK 导入到应用程序中。如我们的文档中所述,有多种方法可以做到这一点。例如,您可以从我们的 CDN 导入库。或者您可以使用 npm 在本地安装它,如果您使用 Browserify,则将其打包到您的应用程序中。
我们将从 npm 获取 Firebase SDK 并使用Webpack来捆绑我们的代码。我们这样做是为了让 Webpack 可以删除任何不必要的代码,使我们的 JS 包大小保持较小,以确保我们的应用程序尽快加载。对于此 Codelab,我们已经创建了一个包含 Firebase SDK 作为依赖项的web-start/package.json
文件,并在web-start/src/index.js
的顶部导入了所需的函数。
包.json
"dependencies": {
"firebase": "^9.0.0"
}
索引.js
import { initializeApp } from 'firebase/app';
import {
getAuth,
onAuthStateChanged,
GoogleAuthProvider,
signInWithPopup,
signOut,
} from 'firebase/auth';
import {
getFirestore,
collection,
addDoc,
query,
orderBy,
limit,
onSnapshot,
setDoc,
updateDoc,
doc,
serverTimestamp,
} from 'firebase/firestore';
import {
getStorage,
ref,
uploadBytesResumable,
getDownloadURL,
} from 'firebase/storage';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getPerformance } from 'firebase/performance';
在此 Codelab 中,我们将使用 Firebase Authentication、Cloud Firestore、Cloud Storage、Cloud Messaging 和 Performance Monitoring,因此我们将导入它们的所有库。在您未来的应用程序中,请确保您只导入您需要的 Firebase 部分,以缩短应用程序的加载时间。
安装 Firebase SDK 并开始构建 Webpack
我们需要运行一些命令来构建我们的应用程序。
- 打开一个新的终端窗口
- 确保你在
web-start
目录中 - 运行
npm install
下载 Firebase SDK - 运行
npm run start
以启动 Webpack。 Webpack 现在将继续为 Codelab 的其余部分重建我们的源代码。
配置火力地堡
我们还需要配置 Firebase SDK 以告知它我们正在使用哪个 Firebase 项目。
- 转到Firebase 控制台中的项目设置
- 在“您的应用”卡片中,选择您需要配置对象的应用的昵称。
- 从 Firebase SDK 片段窗格中选择“配置”。
- 复制配置对象片段,然后将其添加到
web-start/src/firebase-config.js
。
firebase-config.js
const config = {
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",
};
现在,转到web-start/src/index.js
的底部并初始化 Firebase:
索引.js
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);
7.设置用户登录
Firebase SDK 现在应该可以使用了,因为它已在index.js
中导入和初始化。我们现在要使用Firebase Authentication实现用户登录。
使用 Google 登录验证您的用户
在应用程序中,当用户单击“使用 Google 登录”按钮时,会触发signIn
功能。 (我们已经为您设置好!)对于此 Codelab,我们希望授权 Firebase 使用 Google 作为身份提供者。我们将使用弹出窗口,但 Firebase 提供了其他几种方法。
- 在
web-start
目录的子目录src/
中,打开index.js
。 - 找到函数
signIn
。 - 用以下代码替换整个函数。
索引.js
// Signs-in Friendly Chat.
async function signIn() {
// Sign in Firebase using popup auth and Google as the identity provider.
var provider = new GoogleAuthProvider();
await signInWithPopup(getAuth(), provider);
}
signOut
函数在用户点击Sign out按钮时被触发。
- 返回文件
src/index.js
。 - 找到函数
signOutUser
。 - 用以下代码替换整个函数。
索引.js
// Signs-out of Friendly Chat.
function signOutUser() {
// Sign out of Firebase.
signOut(getAuth());
}
跟踪身份验证状态
要相应地更新我们的 UI,我们需要一种方法来检查用户是登录还是注销。使用 Firebase 身份验证,您可以在身份验证状态上注册观察者,每次身份验证状态更改时都会触发该观察者。
- 返回文件
src/index.js
。 - 找到函数
initFirebaseAuth
。 - 用以下代码替换整个函数。
索引.js
// Initialize firebase auth
function initFirebaseAuth() {
// Listen to auth state changes.
onAuthStateChanged(getAuth(), authStateObserver);
}
上面的代码将函数authStateObserver
注册为身份验证状态观察器。它会在每次身份验证状态更改时触发(当用户登录或注销时)。此时,我们将更新 UI 以显示或隐藏登录按钮、注销按钮、已登录用户的个人资料图片等。所有这些 UI 部分都已实现。
显示登录用户的信息
我们想在我们应用的顶部栏中显示登录用户的个人资料图片和用户名。在 Firebase 中,已登录用户的数据始终在currentUser
对象中可用。早些时候,我们将authStateObserver
函数设置为在用户登录时触发,以便我们的 UI 相应更新。触发时它将调用getProfilePicUrl
和getUserName
。
- 返回文件
src/index.js
。 - 找到函数
getProfilePicUrl
和getUserName
。 - 用以下代码替换这两个函数。
索引.js
// Returns the signed-in user's profile Pic URL.
function getProfilePicUrl() {
return getAuth().currentUser.photoURL || '/images/profile_placeholder.png';
}
// Returns the signed-in user's display name.
function getUserName() {
return getAuth().currentUser.displayName;
}
如果用户在未登录时尝试发送消息,我们会显示一条错误消息。(不过你可以试试!)因此,我们需要检测用户是否确实已登录。
- 返回文件
src/index.js
。 - 找到函数
isUserSignedIn
。 - 用以下代码替换整个函数。
索引.js
// Returns true if a user is signed-in.
function isUserSignedIn() {
return !!getAuth().currentUser;
}
测试登录应用程序
- 如果您的应用程序仍在提供服务,请在浏览器中刷新您的应用程序。否则,在命令行上运行
firebase serve --only hosting
以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。 - 使用登录按钮和您的 Google 帐户登录应用程序。如果您看到一条错误消息,指出
auth/operation-not-allowed
,请检查以确保您在 Firebase 控制台中启用了 Google Sign-in 作为身份验证提供程序。 - 登录后,应显示您的个人资料图片和用户名:
8. 向 Cloud Firestore 写入消息
在本部分中,我们将向 Cloud Firestore 写入一些数据,以便我们可以填充应用的界面。这可以通过Firebase 控制台手动完成,但我们将在应用程序本身中完成,以演示基本的 Cloud Firestore 写入。
数据模型
Cloud Firestore 数据分为集合、文档、字段和子集合。我们将聊天的每条消息作为文档存储在名为messages
顶级集合中。
将消息添加到 Cloud Firestore
为了存储用户编写的聊天消息,我们将使用Cloud Firestore 。
在本节中,您将为用户添加将新消息写入数据库的功能。用户点击发送按钮将触发下面的代码片段。它将包含消息字段内容的消息对象添加到messages
集合中的 Cloud Firestore 实例。 add()
方法将具有自动生成的 ID 的新文档添加到集合中。
- 返回文件
src/index.js
。 - 找到函数
saveMessage
。 - 用以下代码替换整个函数。
索引.js
// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
// Add a new message entry to the Firebase database.
try {
await addDoc(collection(getFirestore(), 'messages'), {
name: getUserName(),
text: messageText,
profilePicUrl: getProfilePicUrl(),
timestamp: serverTimestamp()
});
}
catch(error) {
console.error('Error writing new message to Firebase Database', error);
}
}
测试发送消息
- 如果您的应用程序仍在提供服务,请在浏览器中刷新您的应用程序。否则,在命令行上运行
firebase serve --only hosting
以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。 - 登录后,输入一条消息,例如“Hey there!”,然后单击“发送” 。这会将消息写入 Cloud Firestore。但是,您还不会在实际的 Web 应用程序中看到数据,因为我们仍然需要实现数据检索(代码实验室的下一部分)。
- 您可以在 Firebase 控制台中看到新添加的消息。打开您的 Firebase 控制台。在构建部分下,单击Firestore 数据库(或单击此处并选择您的项目),您应该会看到包含新添加消息的消息集合:
9.阅读消息
同步消息
要在应用程序中读取消息,我们需要添加在数据更改时触发的侦听器,然后创建一个显示新消息的 UI 元素。
我们将添加代码来侦听来自应用程序的新添加消息。在此代码中,我们将注册侦听数据更改的侦听器。我们将只显示聊天的最后 12 条消息,以避免在加载时显示很长的历史记录。
- 返回文件
src/index.js
。 - 找到函数
loadMessages
。 - 用以下代码替换整个函数。
索引.js
// 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.
const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
// Start listening to the query.
onSnapshot(recentMessagesQuery, 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 文档中阅读更多相关信息。
测试同步消息
- 如果您的应用程序仍在提供服务,请在浏览器中刷新您的应用程序。否则,在命令行上运行
firebase serve --only hosting
以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。 - 您之前创建到数据库中的消息应该显示在 FriendlyChat UI 中(见下文)。随意写新消息;他们应该立即出现。
- (可选)您可以尝试直接在 Firebase 控制台的数据库部分手动删除、修改或添加新消息;任何更改都应反映在用户界面中。
恭喜!您正在您的应用中阅读 Cloud Firestore 文档!
10.发送图片
我们现在将添加一个共享图像的功能。
Cloud Firestore 适合存储结构化数据,而 Cloud Storage 更适合存储文件。 Cloud Storage for Firebase是一种文件/blob 存储服务,我们将使用它来存储用户使用我们的应用程序共享的任何图像。
将图像保存到云存储
对于此 Codelab,我们已经为您添加了一个可触发文件选择器对话框的按钮。选择文件后,调用saveImageMessage
函数,可以获取到所选文件的引用。 saveImageMessage
函数完成以下操作:
- 在聊天提要中创建“占位符”聊天消息,以便用户在我们上传图片时看到“正在加载”动画。
- 将图像文件上传到云存储到此路径:
/<uid>/<messageId>/<file_name>
- 为图像文件生成一个公开可读的 URL。
- 使用新上传的图像文件的 URL 代替临时加载图像更新聊天消息。
现在您将添加发送图像的功能:
- 返回文件
src/index.js
。 - 找到函数
saveImageMessage
。 - 用以下代码替换整个函数。
索引.js
// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
async function saveImageMessage(file) {
try {
// 1 - We add a message with a loading icon that will get updated with the shared image.
const messageRef = await addDoc(collection(getFirestore(), 'messages'), {
name: getUserName(),
imageUrl: LOADING_IMAGE_URL,
profilePicUrl: getProfilePicUrl(),
timestamp: serverTimestamp()
});
// 2 - Upload the image to Cloud Storage.
const filePath = `${getAuth().currentUser.uid}/${messageRef.id}/${file.name}`;
const newImageRef = ref(getStorage(), 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.
await updateDoc(messageRef,{
imageUrl: publicImageUrl,
storageUri: fileSnapshot.metadata.fullPath
});
} catch (error) {
console.error('There was an error uploading a file to Cloud Storage:', error);
}
}
测试发送图片
- 如果您的应用程序仍在提供服务,请在浏览器中刷新您的应用程序。否则,在命令行上运行
firebase serve --only hosting
以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。 - 登录后点击图片上传按钮
并使用文件选择器选择图像文件。如果您正在寻找图片,请随意使用这张漂亮的咖啡杯图片。
- 一条新消息应该会出现在应用程序的 UI 中,其中包含您选择的图像:
如果您尝试在未登录的情况下添加图像,您应该会看到一条 Toast 通知,告诉您必须登录才能添加图像。
11.显示通知
我们现在将添加对浏览器通知的支持。该应用程序将在聊天中发布新消息时通知用户。 Firebase 云消息传递(FCM) 是一种跨平台消息传递解决方案,可让您免费可靠地传递消息和通知。
添加 FCM 服务工作者
Web 应用程序需要一个service worker来接收和显示 web 通知。
- 在
web-start
目录的src
目录中,打开firebase-messaging-sw.js
。 - 将以下内容添加到该文件。
firebase-messaging-sw.js
// Import and configure the Firebase SDK
import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { getFirebaseConfig } from './firebase-config';
const firebaseApp = initializeApp(getFirebaseConfig());
getMessaging(firebaseApp);
console.info('Firebase messaging service worker is set up');
Service Worker 只需加载和初始化 Firebase Cloud Messaging SDK,它将负责显示通知。
获取 FCM 设备令牌
在设备或浏览器上启用通知后,您将获得一个设备令牌。这个设备令牌是我们用来向特定设备或特定浏览器发送通知的。
当用户登录时,我们调用saveMessagingDeviceToken
函数。这就是我们从浏览器获取FCM 设备令牌并将其保存到 Cloud Firestore 的地方。
- 返回文件
src/index.js
。 - 找到函数
saveMessagingDeviceToken
。 - 用以下代码替换整个函数。
索引.js
// Saves the messaging device token to Cloud Firestore.
async function saveMessagingDeviceToken() {
try {
const currentToken = await getToken(getMessaging());
if (currentToken) {
console.log('Got FCM device token:', currentToken);
// Saving the Device Token to Cloud Firestore.
const tokenRef = doc(getFirestore(), 'fcmTokens', currentToken);
await setDoc(tokenRef, { uid: getAuth().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(getMessaging(), (message) => {
console.log(
'New foreground notification from Firebase Messaging!',
message.notification
);
});
} else {
// Need to request permissions to show notifications.
requestNotificationsPermissions();
}
} catch(error) {
console.error('Unable to get messaging token.', error);
};
}
但是,此代码最初不起作用。为了让您的应用能够检索设备令牌,用户需要授予您的应用显示通知的权限(代码实验室的下一步)。
请求显示通知的权限
当用户尚未授予您的应用程序显示通知的权限时,您将不会获得设备令牌。在这种情况下,我们调用firebase.messaging().requestPermission()
方法,这将显示一个浏览器对话框,请求此权限(在支持的浏览器中)。
- 返回文件
src/index.js
。 - 找到函数
requestNotificationsPermissions
。 - 用以下代码替换整个函数。
索引.js
// Requests permissions to show notifications.
async function requestNotificationsPermissions() {
console.log('Requesting notifications permission...');
const permission = await Notification.requestPermission();
if (permission === 'granted') {
console.log('Notification permission granted.');
// Notification permission granted.
await saveMessagingDeviceToken();
} else {
console.log('Unable to get permission to notify.');
}
}
获取您的设备令牌
- 如果您的应用程序仍在提供服务,请在浏览器中刷新您的应用程序。否则,在命令行上运行
firebase serve --only hosting
以从http://localhost:5000开始为应用程序提供服务,然后在浏览器中打开它。 - 登录后,应出现通知权限对话框:
- 单击允许。
- 打开浏览器的 JavaScript 控制台。您应该看到以下消息:
Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
- 复制您的设备令牌。您将在 Codelab 的下一阶段需要它。
向您的设备发送通知
现在您有了设备令牌,您可以发送通知。
- 打开Firebase 控制台的云消息传递选项卡。
- 点击“新通知”
- 输入通知标题和通知文本。
- 在屏幕右侧,单击“发送测试消息”
- 输入您从浏览器的 JavaScript 控制台复制的设备令牌,然后单击加号 ("+")
- 点击“测试”
如果您的应用程序在前台,您将在 JavaScript 控制台中看到通知。
如果您的应用程序在后台运行,则您的浏览器中应该会出现一条通知,如下例所示:
12. 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;
}
}
}
更新数据库安全规则
有两种方法可以编辑数据库安全规则,一种是在 Firebase 控制台中,另一种是使用 Firebase CLI 部署的本地规则文件。
要在 Firebase 控制台中更新安全规则:
- 从左侧面板转到数据库部分,然后单击规则选项卡。
- 用上面显示的规则替换控制台中已有的默认规则。
- 单击发布。
从本地文件更新安全规则:
- 在
web-start
目录中,打开firestore.rules
。 - 用上面显示的规则替换文件中已有的默认规则。
- 在
web-start
目录中,打开firebase.json
。 - 添加指向
firestore.rules
firestore.rules
,如下所示。 (hosting
属性应该已经在文件中。)
firebase.json
{
// Add this!
"firestore": {
"rules": "firestore.rules"
},
"hosting": {
"public": "./public"
}
}
- 通过运行以下命令使用 Firebase CLI 部署安全规则:
firebase deploy --only firestore
- 您的命令行应显示以下响应:
=== 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
13.云存储安全规则
查看 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 控制台中更新安全规则:
- 从左侧面板转到“存储”部分,然后单击“规则”选项卡。
- 用上面显示的规则替换控制台中已有的默认规则。
- 单击发布。
从本地文件更新安全规则:
- 在
web-start
目录中,打开storage.rules
。 - 用上面显示的规则替换文件中已有的默认规则。
- 在
web-start
目录中,打开firebase.json
。 - 添加指向
storage.rules
文件的storage.rules
属性,如下所示。 (hosting
和database
属性应该已经在文件中。)
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"
}
}
- 通过运行以下命令使用 Firebase CLI 部署安全规则:
firebase deploy --only storage
- 您的命令行应显示以下响应:
=== 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
14.收集性能数据
您可以使用 Performance Monitoring SDK 从您的应用程序收集真实的性能数据,然后在 Firebase 控制台中查看和分析该数据。性能监控可帮助您了解可以在何处以及何时改进应用程序的性能,以便您可以使用该信息来解决性能问题。
可以通过多种方式与 Firebase Performance Monitoring JavaScript SDK 集成。在此 Codelab 中,我们从托管 URL启用了性能监控。请参阅文档以查看启用 SDK 的其他方法。
自动痕迹
由于我们已经在web-start/src/index.js
的顶部导入了getPerformance
,我们只需要添加一行来告诉性能监控在用户访问您部署的站点时自动为您收集页面负载和网络请求指标!
- 在
web-start/src/index.js
中,在现有TODO
下方添加以下行以初始化性能监控。
索引.js
// TODO: Enable Firebase Performance Monitoring.
getPerformance();
测量第一个输入延迟(可选)
首次输入延迟很有用,因为浏览器对用户交互的响应给了用户对应用程序响应能力的第一印象。
首次输入延迟在用户首次与页面上的元素交互时开始,例如单击按钮或超链接。它在浏览器能够响应输入后立即停止,这意味着浏览器不忙于加载或解析您的页面内容。
如果您想测量第一个输入延迟,则需要直接包含以下代码。
- 打开
public/index.html
。 - 取消注释以下行中的
script
标记。
<!-- 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 控制台中看到的有关页面加载性能的指标:
当您将性能监控 SDK 集成到您的应用程序中时,您无需编写任何其他代码,您的应用程序就会开始自动监控性能的几个关键方面。对于 Web 应用程序,SDK 会记录诸如首次内容绘制、用户与您的应用程序交互的能力等方面。
您还可以设置自定义跟踪、指标和属性来衡量应用程序的特定方面。访问文档以了解有关自定义跟踪和指标以及自定义属性的更多信息。
15. 使用 Firebase 托管部署您的应用
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"
)。
- 确保您的命令行正在访问您应用程序的本地
web-start
目录。 - 通过运行以下命令将文件部署到 Firebase 项目:
firebase deploy --except functions
- 控制台应显示以下内容:
=== 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
- 在您自己的两个 Firebase 子域中使用 Firebase 托管访问您现在完全托管在全球 CDN 上的 Web 应用程序:
-
https://<firebase-projectId>.firebaseapp.com
-
https://<firebase-projectId>.web.app
或者,您可以在命令行中运行firebase open hosting:site
。
访问文档以了解有关 Firebase Hosting 工作原理的更多信息。
转到项目的 Firebase 控制台托管部分,查看有用的托管信息和工具,包括部署历史、回滚到应用程序以前版本的功能,以及设置自定义域的工作流程。
16. 恭喜!
您已经使用 Firebase 构建了一个实时聊天网络应用程序!
我们涵盖的内容
- Firebase 身份验证
- 云端 Firestore
- 用于云存储的 Firebase SDK
- Firebase 云消息传递
- Firebase 性能监控
- 火力地堡托管