在此代碼實驗室中,您將學習如何使用Firebase通過使用Firebase產品和服務實現和部署聊天客戶端來輕鬆創建Web應用程序。
您將學到什麼
- 使用Cloud Firestore和Cloud Storage for Firebase同步數據。
- 使用Firebase身份驗證對用戶進行身份驗證。
- 在Firebase託管上部署您的Web應用。
- 使用Firebase Cloud Messaging發送通知。
- 收集您的Web應用程序的性能數據。
你需要什麼
從命令行克隆代碼實驗室的GitHub存儲庫:
git clone https://github.com/firebase/codelab-friendlychat-web
或者,如果您尚未安裝git,則可以 將存儲庫下載為ZIP文件。
導入入門應用
使用您的IDE,從克隆的存儲庫中打開或導入web-start
目錄。此📁Web web-start
目錄包含codelab的啟動代碼,它將是一個功能齊全的聊天Web應用程序。
創建一個Firebase項目
- 登錄到Firebase 。
- 在Firebase控制台中,單擊“添加項目” ,然後將您的Firebase項目命名為FriendlyChat 。記住您的Firebase項目的項目ID。
- 單擊創建項目。
我們將要構建的應用程序使用可用於Web應用程序的Firebase產品:
- Firebase身份驗證可輕鬆允許您的用戶登錄您的應用。
- Cloud Firestore可將結構化數據保存在雲上,並在數據更改時立即獲得通知。
- 用於Firebase的Cloud Storage將文件保存在雲中。
- Firebase Hosting託管和服務您的資產。
- Firebase Cloud Messaging發送推送通知並顯示瀏覽器彈出通知。
- Firebase Performance Monitoring,以收集您應用程序的用戶性能數據。
其中一些產品需要特殊配置或需要使用Firebase控制台啟用。
將Firebase Web應用添加到項目
- 點擊網頁圖標
創建一個新的Firebase Web應用程序。
- 使用暱稱“友好聊天”註冊該應用程序,然後選中“同時為此應用程序設置Firebase託管”旁邊的框。點擊註冊應用。
- 單擊其餘步驟。您現在無需按照說明進行操作;這些將在本代碼實驗室的後續步驟中介紹。
為Firebase身份驗證啟用Google登錄
為了允許用戶使用其Google帳戶登錄網絡應用,我們將使用Google登錄方法。
您需要啟用Google登錄:
- 在Firebase控制台中,找到左側面板中的“開發”部分。
- 點擊身份驗證,然後點擊登錄方法標籤(或點擊此處直接轉到此處)。
- 啟用Google登錄提供程序,然後點擊保存。
- 將您應用的公開名稱設置為“友好聊天” ,然後從下拉菜單中選擇一個項目支持電子郵件。
- 在Google Cloud Console中配置您的OAuth同意屏幕。添加徽標,
啟用Cloud Firestore
該Web應用程序使用Cloud Firestore保存聊天消息並接收新的聊天消息。
您需要啟用Cloud Firestore:
- 在Firebase控制台的“開發”部分中,單擊“數據庫” 。
- 在“ Cloud Firestore”窗格中,單擊“創建數據庫”。
- 選擇“以測試模式啟動”選項,然後在閱讀有關安全規則的免責聲明後單擊“下一步” 。
測試模式確保我們可以在開發過程中自由地寫入數據庫。我們稍後將在此代碼實驗室中使數據庫更安全。
- 設置Cloud Firestore數據的存儲位置。您可以將其保留為默認設置,也可以選擇一個靠近您的區域。單擊“完成”以配置Firestore。
啟用雲存儲
該Web應用程序使用Cloud Storage for Firebase來存儲,上傳和共享圖片。
您需要啟用雲存儲:
- 在Firebase控制台的“開發”部分中,單擊“存儲” 。
- 單擊開始。
- 閱讀有關Firebase項目安全規則的免責聲明,然後單擊“下一步” 。
使用默認的安全規則,任何經過身份驗證的用戶都可以將任何內容寫入Cloud Storage。在本代碼實驗室的後面,我們將使存儲更加安全。
- 已預先為Cloud Storage位置選擇與您為Cloud Firestore數據庫選擇的區域相同的區域。單擊完成以完成設置。
Firebase命令行界面(CLI)允許您使用Firebase Hosting在本地提供Web應用程序,以及將Web應用程序部署到Firebase項目。
- 通過運行以下npm命令來安裝CLI:
npm -g install firebase-tools
- 通過運行以下命令,驗證CLI已正確安裝:
firebase --version
確保Firebase CLI的版本為v4.1.0或更高版本。
- 通過運行以下命令來授權Firebase CLI:
firebase login
我們已經設置了Web應用程序模板,以從應用程序的本地目錄(您之前在代碼實驗室中克隆的存儲庫)中提取Firebase Hosting的應用程序配置。但是要提取配置,我們需要將您的應用程序與Firebase項目關聯。
- 確保您的命令行正在訪問應用程序的本地
web-start
目錄。 - 通過運行以下命令將您的應用程序與Firebase項目相關聯:
firebase use --add
- 出現提示時,選擇您的Project ID ,然後為您的Firebase項目命名。
如果您有多個環境(生產,暫存等),則別名很有用。但是,對於此代碼實驗室,我們僅使用default
的別名。
- 請按照命令行上的其餘說明進行操作。
現在,您已經導入並配置了項目,就可以開始運行Web應用程序了。
- 在
web-start
目錄的控制台中,運行以下Firebase CLI命令:
firebase serve --only hosting
- 您的命令行應顯示以下響應:
✔ hosting: Local server: http://localhost:5000
我們正在使用Firebase託管模擬器在本地提供應用程序。現在應該可以從http:// localhost:5000訪問該Web應用程序。將提供位於public
子目錄下的所有文件。
- 使用瀏覽器,通過http:// localhost:5000打開您的應用程序。
您應該看到FriendlyChat應用程序的用戶界面,該用戶界面尚未運行(但!):
該應用目前無法執行任何操作,但在您的幫助下,它將很快!到目前為止,我們僅為您佈置了用戶界面。
現在讓我們建立一個實時聊天!
導入Firebase SDK
我們需要將Firebase SDK導入到應用程序中。如我們的文檔中所述,有多種方法可以執行此操作。例如,您可以從我們的CDN導入庫。或者,您可以使用npm在本地安裝它,然後使用Browserify將其打包在您的應用中。
由於我們使用Firebase Hosting服務我們的應用程序,因此我們將導入文件index.html
(位於web-start/public/
目錄中)中的本地URL。對於此代碼實驗室,我們已經在index.html
文件的底部為您添加了以下幾行,但是您可以再次檢查它們是否在其中。
index.html
<script src="/__/firebase/6.4.0/firebase-app.js"></script>
<script src="/__/firebase/6.4.0/firebase-auth.js"></script>
<script src="/__/firebase/6.4.0/firebase-storage.js"></script>
<script src="/__/firebase/6.4.0/firebase-messaging.js"></script>
<script src="/__/firebase/6.4.0/firebase-firestore.js"></script>
<script src="/__/firebase/6.4.0/firebase-performance.js"></script>
在此代碼實驗室中,我們將使用Firebase身份驗證,Cloud Firestore,Cloud Storage,Cloud Messaging和性能監控,因此我們將導入其所有庫。在將來的應用程序中,請確保僅導入所需的Firebase部分,以縮短應用程序的加載時間。
配置Firebase
我們還需要配置Firebase SDK來告訴它我們正在使用哪個Firebase項目。由於我們使用的是Firebase託管,因此您可以導入一個特殊的腳本來為您執行此配置。同樣,對於此代碼實驗室,我們已經在public/index.html
文件的底部為您添加了以下行,但是請仔細檢查它是否存在。
index.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 Authentication實施用戶登錄。
使用Google登錄身份驗證您的用戶
在應用程序中,當用戶單擊“使用Google登錄”按鈕時,將觸發signIn
功能。 (我們已經為您設置好了!)對於此代碼實驗室,我們想授權Firebase使用Google作為身份提供者。我們將使用一個彈出窗口,但是Firebase可以使用其他幾種方法。
- 在
web-start
目錄中的public/scripts/
子目錄中,打開main.js
- 找到功能
signIn
。 - 用以下代碼替換整個功能。
main.js
// 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
當用戶點擊退出按鈕功能被觸發。
- 返回文件
public/scripts/main.js
- 找到功能
signOut
。 - 用以下代碼替換整個函數。
main.js
第069章追踪認證狀態
要相應地更新我們的UI,我們需要一種檢查用戶是否已登錄或註銷的方法。使用Firebase身份驗證,可以在每次身份驗證狀態更改時都會觸發的身份驗證狀態上註冊觀察者。
- 返回文件
public/scripts/main.js
- 找到函數
initFirebaseAuth
。 - 用以下代碼替換整個功能。
main.js
// Initiate Firebase Auth.
function initFirebaseAuth() {
// Listen to auth state changes.
firebase.auth().onAuthStateChanged(authStateObserver);
}
上面的代碼將功能authStateObserver
註冊為身份驗證狀態觀察者。每當身份驗證狀態更改時(用戶登錄或註銷時),它將觸發。此時,我們將更新UI以顯示或隱藏登錄按鈕,退出按鈕,已登錄用戶的個人資料圖片等。所有這些UI部分均已實現。
顯示已登錄用戶的信息
我們要在應用程序的頂部欄中顯示已登錄用戶的個人資料圖片和用戶名。在Firebase中,登錄用戶的數據始終在firebase.auth().currentUser
像中可用。之前,我們將authStateObserver
函數設置為在用戶authStateObserver
時觸發,以便我們的UI相應地更新。觸發時將調用getProfilePicUrl
和getUserName
。
- 返回文件
public/scripts/main.js
- 找到函數
getProfilePicUrl
和getUserName
。 - 用下面的代碼替換這兩個函數。
main.js
// 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;
}
如果用戶在未登錄時嘗試發送消息,我們將顯示一條錯誤消息。(但是,您可以嘗試!)因此,我們需要檢測用戶是否實際上已登錄。
- 返回文件
public/scripts/main.js
- 找到函數
isUserSignedIn
。 - 用以下代碼替換整個功能。
main.js
// Returns true if a user is signed-in.
function isUserSignedIn() {
return !!firebase.auth().currentUser;
}
測試登錄到應用程序
- 如果您的應用仍在提供中,請在瀏覽器中刷新您的應用。否則,請在命令行上運行
firebase serve --only hosting
從http:// localhost:5000開始提供應用程序,然後在瀏覽器中將其打開。 - 使用登錄按鈕和您的Google帳戶登錄該應用。如果您看到錯誤消息,說明
auth/operation-not-allowed
,請檢查並確保您在Firebase控制台中啟用了Google登錄作為身份驗證提供程序 - 登錄後,您的個人資料圖片和用戶名應顯示:
在本部分中,我們將一些數據寫入Cloud Firestore,以便我們可以填充應用程序的UI。可以使用Firebase控制台手動完成此操作,但我們將在應用程序本身中完成此操作,以演示Cloud Firestore的基本寫操作。
資料模型
Cloud Firestore數據分為集合,文檔,字段和子集合。我們會將聊天的每個消息作為文檔存儲在稱為messages
的頂級集合中。
將消息添加到Cloud Firestore
要存儲用戶編寫的聊天消息,我們將使用Cloud Firestore 。
在本部分中,您將添加功能,以便用戶將新消息寫入數據庫。用戶單擊“發送”按鈕將觸發以下代碼段。它將帶有消息字段內容的消息對象添加到messages
集合中的Cloud Firestore實例。 add()
方法將具有自動生成的ID的新文檔添加到集合中。
- 返回文件
public/scripts/main.js
- 找到功能
saveMessage
。 - 用以下代碼替換整個功能。
main.js
// 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);
});
}
測試發送消息
- 如果您的應用仍在提供中,請在瀏覽器中刷新您的應用。否則,請在命令行上運行
firebase serve --only hosting
從http:// localhost:5000開始為應用提供服務,然後在瀏覽器中將其打開。 - 登錄後,輸入諸如“ Hey there!”的消息,然後單擊“ SEND” 。這會將消息寫入Cloud Firestore。但是,您仍無法在實際的Web應用程序中看到數據,因為我們仍然需要實現檢索數據(代碼實驗室的下一部分)。
- 您可以在Firebase控制台中看到新添加的消息。打開您的Firebase控制台。在“開發”部分下,單擊“數據庫” (或單擊此處並選擇您的項目),您應該看到包含新添加的消息的消息集合:
同步消息
要在應用中閱讀消息,我們需要添加在數據更改時觸發的偵聽器,然後創建一個顯示新消息的UI元素。
我們將添加代碼來偵聽來自應用程序的新添加的消息。在此代碼中,我們將註冊用於監聽對數據所做的更改的監聽器。我們將僅顯示聊天的最後12條消息,以避免在加載時顯示很長的歷史記錄。
- 返回文件
public/scripts/main.js
- 找到功能
loadMessages
。 - 用以下代碼替換整個功能。
main.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.
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文檔中閱讀有關此內容的更多信息。
測試同步消息
- 如果您的應用仍在提供中,請在瀏覽器中刷新您的應用。否則,請在命令行上運行
firebase serve --only hosting
從http:// localhost:5000開始提供應用程序,然後在瀏覽器中將其打開。 - 您先前在數據庫中創建的消息應顯示在FriendlyChat UI中(請參見下文)。隨時編寫新消息;它們應該立即出現。
- (可選)您可以嘗試直接在Firebase控制台的“數據庫”部分中手動刪除,修改或添加新消息。任何更改都應反映在用戶界面中。
恭喜你!您正在閱讀應用程序中的Cloud Firestore文檔!
現在,我們將添加共享圖像的功能。
儘管Cloud Firestore適合存儲結構化數據,但Cloud Storage更適合存儲文件。 Cloud Storage for Firebase是一種文件/ blob存儲服務,我們將使用它來存儲用戶使用我們的應用共享的任何圖像。
將圖像保存到雲存儲
對於此代碼實驗室,我們已經為您添加了一個觸發文件選擇器對話框的按鈕。選擇文件後,將saveImageMessage
函數,您可以獲取對所選文件的引用。 saveImageMessage
函數完成以下任務:
- 在聊天供稿中創建“佔位符”聊天消息,以便用戶在上載圖像時看到“正在加載”動畫。
- 將映像文件上傳到Cloud Storage到以下路徑:
/<uid>/<messageId>/<file_name>
- 生成圖像文件的公共可讀URL。
- 用新上傳的圖像文件的URL代替臨時加載圖像更新聊天消息。
現在,您將添加發送圖像的功能:
- 返回文件
public/scripts/main.js
- 找到功能
saveImageMessage
。 - 用以下代碼替換整個函數。
main.js
// 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);
});
}
測試發送圖像
- 如果您的應用仍在提供中,請在瀏覽器中刷新您的應用。否則,請在命令行上運行
firebase serve --only hosting
從http:// localhost:5000開始提供應用程序,然後在瀏覽器中將其打開。 - 登錄後,點擊圖片上傳按鈕
並使用文件選擇器選擇圖像文件。如果您正在尋找圖像,請隨時使用這張精美的咖啡杯圖片。
- 新消息應顯示在應用程序的用戶界面中,並帶有您選擇的圖像:
如果您嘗試在未登錄時添加圖像,則應該看到一條Toast通知,告知您必須登錄才能添加圖像。
現在,我們將添加對瀏覽器通知的支持。當新消息發佈在聊天中時,該應用程序將通知用戶。 Firebase雲消息傳遞(FCM)是一種跨平台的消息傳遞解決方案,可讓您可靠地免費傳遞消息和通知。
將GCM發送者ID列入白名單
在Web應用程序清單中,您需要指定gcm_sender_id
,這是一個硬編碼值,指示FCM被授權向該應用程序發送消息。
- 在
web-start
目錄的public
目錄中,打開manifest.json
。 - 完全如下所示,將瀏覽器發件人ID值添加到
gcm_sender_id
屬性中。不要更改下面顯示的值。
manifest.json
{
"name": "Friendly Chat",
"short_name": "Friendly Chat",
"start_url": "/index.html",
"display": "standalone",
"orientation": "portrait",
"gcm_sender_id": "103953800507"
}
添加FCM服務工作者
Web應用程序需要一名服務人員,該服務人員將接收並顯示Web通知。
- 在
web-start
目錄的public
目錄中,創建一個名為firebase-messaging-sw.js
的新文件。 - 將以下內容添加到該新文件。
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();
服務人員只需加載並初始化Firebase Cloud Messaging SDK,即可處理顯示通知。
獲取FCM設備令牌
在設備或瀏覽器上啟用通知後,系統會為您提供設備令牌。該設備令牌是我們用來向特定設備或特定瀏覽器發送通知的工具。
當用戶saveMessagingDeviceToken
,我們調用saveMessagingDeviceToken
函數。那就是我們從瀏覽器獲取FCM設備令牌並將其保存到Cloud Firestore的地方。
- 返回文件
public/scripts/main.js
- 找到函數
saveMessagingDeviceToken
。 - 用以下代碼替換整個功能。
main.js
// 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()
方法,該方法將顯示一個瀏覽器對話框,詢問該權限(在受支持的瀏覽器中)。
- 返回文件
public/scripts/main.js
- 找到功能
requestNotificationsPermissions
。 - 用以下代碼替換整個功能。
main.js
// 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);
});
}
獲取設備令牌
- 如果您的應用仍在提供中,請在瀏覽器中刷新您的應用。否則,請在命令行上運行
firebase serve --only hosting
從http:// localhost:5000開始為應用提供服務,然後在瀏覽器中將其打開。 - 登錄後,將顯示通知權限對話框:
- 點擊允許。
- 打開瀏覽器的JavaScript控制台。您應該看到以下消息:
Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
- 複製您的設備令牌。您將在下一階段的代碼實驗室中使用它。
發送通知到您的設備
現在您有了設備令牌,就可以發送通知了。
- 除了設備令牌之外,您還需要Firebase應用程序的Server Key 。要獲取此密鑰,請轉到Firebase控制台>項目設置> Cloud Messaging ,然後復制服務器密鑰。
要發送通知,您需要發送以下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"
}
- 在命令行上,運行以下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發送的消息。
如果您的應用程序在後台運行,則通知應顯示在瀏覽器中,如以下示例所示:
查看數據庫安全規則
Cloud Firestore使用特定的規則語言來定義訪問權限,安全性和數據驗證。
在此代碼實驗室的開頭設置Firebase項目時,我們選擇使用“測試模式”默認安全規則,以便不限制對數據存儲的訪問。在Firebase控制台的“數據庫”部分的“規則”選項卡中,您可以查看和修改這些規則。
現在,您應該看到默認規則,該規則不限制對數據存儲的訪問。這意味著任何用戶都可以讀寫您的數據存儲區中的任何集合。
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
我們將使用以下規則更新規則以限制事物:
firestore.rules
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
查看雲存儲安全規則
Cloud Storage for Firebase使用特定的規則語言來定義訪問權限,安全性和數據驗證。
在此代碼實驗室的開頭設置Firebase項目時,我們選擇使用默認的Cloud Storage安全規則,該規則僅允許經過身份驗證的用戶使用Cloud Storage。在Firebase控制台的“存儲”部分的“規則”選項卡中,您可以查看和修改規則。您應該看到默認規則,該規則允許所有已登錄的用戶讀取和寫入存儲桶中的任何文件。
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
我們將更新規則以執行以下操作:
- 允許每個用戶僅寫入自己的特定文件夾
- 允許任何人從Cloud Storage中讀取
- 確保上傳的文件是圖像
- 將可以上傳的圖片大小限制為最大5 MB
可以使用以下規則來實現:
儲存規則
// 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;
}
}
}
更新雲存儲安全規則
有兩種編輯存儲安全規則的方法:在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
您可以使用Performance Monitoring SDK從您的應用程序收集實際性能數據,然後在Firebase控制台中查看和分析該數據。性能監控可幫助您了解可以在何時何地提高應用程序的性能,以便您可以使用該信息來解決性能問題。
有多種方法可以與Firebase Performance Monitoring JavaScript SDK集成。在此代碼實驗室中,我們從託管URL啟用了性能監視。請參閱文檔以查看其他啟用SDK的方法。
自動跟踪
由於我們在代碼實驗室的較早步驟中包含了init.js
firebase-performance.js
和init.js
,因此我們只需要添加一行內容即可告訴Performance Monitoring在用戶訪問您部署的網站時自動為您收集頁面負載和網絡請求指標!
- 在
public/scripts/main.js
,在現有TODO
下方添加以下行以初始化性能監視。
main.js
// TODO: Initialize Firebase Performance Monitoring.
firebase.performance();
測量第一個輸入延遲(可選)
第一次輸入延遲非常有用,因為瀏覽器對用戶交互的響應會給您的用戶關於應用程序響應性的第一印象。
當用戶首次與頁面上的元素進行交互(例如單擊按鈕或超鏈接)時,開始輸入延遲。瀏覽器能夠響應輸入後,它將立即停止,這意味著瀏覽器不忙於加載或解析頁面內容。
如果要測量第一個輸入延遲,則需要直接包含以下代碼。
- 打開
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的更多信息,請參閱文檔。
查看效果數據
由於您尚未部署網站(將在下一步中進行部署),因此下面的屏幕快照顯示了用戶與已部署的網站互動後12個小時內在Firebase控制台中看到的有關頁面加載性能的指標:
當您將Performance Monitoring SDK集成到您的應用中時,您無需編寫任何其他代碼即可在您的應用開始自動監視性能的幾個關鍵方面之前。對於Web應用程序,SDK記錄了諸如第一個內容豐富的繪畫,用戶與您的應用程序進行交互的能力等方面。
您還可以設置自定義跟踪,指標和屬性以衡量應用程序的特定方面。請訪問文檔以了解有關自定義跟踪和指標以及自定義屬性的更多信息。
Firebase提供託管服務,以服務您的資產和Web應用程序。您可以使用Firebase CLI將文件部署到Firebase託管。部署之前,您需要在firebase.json
文件中指定應部署的本地文件。對於此代碼實驗室,我們已經為您完成了此操作,因為在此代碼實驗室期間需要執行此步驟來提供文件。主機設置在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
- 訪問您的Web應用程序,該應用程序現在已經在您自己的兩個Firebase子域中使用Firebase Hosting進行了完全託管:
-
https://<firebase-projectId>.firebaseapp.com
-
https://<firebase-projectId>.web.app
。
另外,您也可以在命令行中運行firebase open hosting:site
。
請訪問文檔以了解有關Firebase託管工作原理的更多信息。
轉到項目的Firebase控制台“主機”部分,以查看有用的主機信息和工具,包括部署的歷史記錄,回滾到應用程序以前版本的功能以及用於設置自定義域的工作流。
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性能監控
- Firebase Hosting