Firebase Web

GCP連動Firebase建立網頁聊天室

Chris Lee
14 min readSep 16, 2020

Firebase 是「後端及服務」的產品,在 2014 年被 Google 收購,目前上面擁有非常豐富的產品資源,以下使用 GCP 進行教學示範,如何聯動 GCP 與 Firebase 服務。

首先開啟GCP後,打開Console畫面進行操作。

進去後我們用git語法複製範例資料,本次示範使用friendlychat-web範例。

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

下面會有兩個程式庫可以使用:

  • web-start:本次教學會使用的初始程式碼
  • web:完整版的範例程式碼
Note:如果要直接使用完整程式碼,記得在Firebase console建立專案互相連接。

建立 Firebase Project

首先先去Firebase的頁面建立專案,連結在此,記得要登入Google帳號,請記得與GCP帳號一致。

點選建立專案,把GCP的專案名稱貼到上面,地區等其他選項勾選參考如下:

建立 Firebase web app

接下來建立 Web App,選擇最右邊的選項,並且輸入 App 名稱,及勾選Firebase Hosting選項。

後面的內容可以略過,認證會在後面步驟完成,無腦下一步就對了。

接下來要允許Google可以登入Firebase,要先允許認證,點擊Authentication,然後Set up sign-in method

  • 允許Google的Sign-in Providers,然後改成Enable。
  • project the public-facing name 打上 “Friendly Chat”。
  • 打上project support email,使用GCP的email。
  • 儲存

啟用 Cloud Firestore

點擊旁邊的Cloud Firestore,點選Create database建立資料庫儲存聊天訊息,為了讓外部可以順利連線,選擇Start in test mode,後面就順著點到底,完成啟用即可。

啟用 Cloud Storage

點擊旁邊的Storage,點選Get Start建立硬碟空間儲存影像等檔案,後面就順著點到底,完成啟用即可。

安裝Firebase command line interface

回到 GCP 的 Console 畫面,使用 firebase cli 開始後續作業,可以使用以下語法安裝,並確認版本:

npm install -g firebase-toolsfirebase --version

接下來進行授權,語法如下:

firebase login --no-localhost

使用no-localhost是因為使用遠端shell操控的關係,之後會跳出Allow Firebase to collect anonymous CLI usage and error reporting information,選擇Y。

然後他會跳一個連結讓你授權,請不要直接點開,把URL複製到新的頁面,進去後會要求你授權,選擇你的GCP帳號進行授權後,複製驗證碼回到Console貼上確認即可。

完成後移動到 friendlychat-web 的 web-start 目錄下。

cd ~/friendlychat-web/web-start/

我們要將專案加入Firebase,會要求命名,可以隨意取名,如 staging。

firebase use --add

如果未來要切換專案 App,可以使用下面語法來切換。

firebase use <alias_name>

部署並開始運行 App

接下來要將服務work起來,使用以下語法:

firebase serve --only hosting

Console會挑出下面訊息,即是代表成功啟動。

i  hosting: Serving hosting files from: ./ 
✔ hosting: Local server: http://localhost:5000

可以直接點擊URL,或是IP帶上5000的prot號都可以開啟服務,如下圖我們的聊天室已經啟動了,但目前只有UI畫面,什麼功能都沒有。

回到 Console 使用 Ctrl+C 跳出服務畫面,我們來完成後續作業。

加入 Firebase 環境設定

為了讓 App 可以運行 Firebase,將 SDK 加入到 App 的畫面中,打開在web-start > public,裡面的 index.html,新增幾行 js 程式碼。

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

原則上如果用官方的範例檔,會幫你把上面程式碼都打好,可以用 GCP 的Code Editor 進行編輯,會比用 vim 或 nano 語法方便的多。

使用者登入設定

聊天室必須知道是誰在講話,所以有使用者登入設定的需求,我們讓聊天室使用 Google 帳號進行登入,並且自動連動到 Google 的帳號認證,首先到 GCP 的側邊欄點選 APIs & Services > Credentials,在 OAuth consent screen 頁面中,將 Application Type 改成 Internal。

完成後我們來改一下 App 上的 js 設定,打開 scripts/main.js 檔案,裡面有很多function,接下來我們將依序修改裡面的程式碼,首先是 singIn

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

再來是singout

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

initFirebaseAuth函數:

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

接下來要顯示使用者資訊在畫面中,共有 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;
}
// Returns true if a user is signed-in.
function isUserSignedIn() {
return !!firebase.auth().currentUser;
}

完成後儲存,並且使用下面語法進行部署:

firebase deploy --except functions

成功後 Console 上會顯示 URL,可以連進去測試登入功能,發現可以用 Google 帳號進行登入,代表成功了。

建立訊息功能並儲存在 Cloud Firestore

接下來要將訊息功能建立起來,並且我們要將訊息儲存在雲端中,每次打開聊天室可以叫出來顯示,一樣打開 public/scripts/main.js,修改幾個程式碼:

// Saves a new message on the Cloud Firestore.
function saveMessage(messageText) {
// Add a new message entry to the Firebase 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 Firebase Database', error);
});
}

以及

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

儲存後一樣使用以下語法部署:

firebase deploy --except functions

完成後就可以去測試訊息功能,可以正常顯示在畫面上了。

我們可以到 Firebase 的網頁中,開啟 Database 頁面,就可以看到訊息儲存在資料庫的樣子。

如此就完成 Firebase 與訊息功能的連動了。

建立圖片功能

圖片功能與訊息功能大同小異,差別是必須有個地方儲存圖片檔,讓其他人可以看到並儲存使用,所以除了 messageID 外還會多了 file_name,我們一樣打開 scripts/main.js 修改幾個程式碼,Medium 程式碼空間不夠寬,建議複製到 Notepad++ 或 sublime 觀看:

// 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 deploy --except functions

接下來去聊天室點擊旁邊的圖片按鈕上傳圖片,就可以進行圖片傳送功能了,你也可以在 Firebase 的 Storage 裡看到上傳的圖片。

這樣就完成一個基本的聊天室功能,可以傳訊息及圖片,並且使用 Google 帳號來辨識使用者是誰,所有架構都使用 GCP 及 Firebase 完成。

後記

Firebase 的功能還有很多,我看過有人用這個建立 Tinder 或 Facebook 的克隆體,有興趣的人都可以去這裡挖寶。

reference:Google qwiklabs GSP 065

--

--

Chris Lee
Chris Lee

Written by Chris Lee

隱身在金融業的資料科學家

No responses yet