Firebase Cloud Functions 基本使用筆記

Firebase Cloud Functions 基本使用筆記

圖片來源:Introducing Cloud Functions for Firebase

本篇要解決的問題

Firebase Cloud Functions 是可以把自己寫的函式,放到 Firebase 上後當後端來使用。

平常用的是 Google Apps Script,但知道可以拿 Cloud Functions 來寫 Node.js 後,就打算把之前寫在 GCP 上的 LINE、Telegram 的二隻機器人移到 Functions,看能不能統一把資料庫跟程式碼都收在 Firebase 中。

本篇是一些 Cloud Functions 的基本使用,包含:安裝、本機測試、觸發、更新 Firestore。

將來有機會會再新增其他 Functions 的相關筆記文。

要注意的是,Cloud Functions 是一項收費的功能,但有提供免費的額度,收費的部份麻煩自行看定價說明:https://cloud.google.com/functions/pricing

參考教學:Firebase Functions


安裝 Firebase CLI

文件:https://firebase.google.com/docs/cli#mac-linux-npm

開啟終端機,輸入:

npm install -g firebase-tools

如果安裝過程中看見很多 ERR!,代表權限不足,Mac 的話就輸入:

sudo npm install -g firebase-tools

輸入密碼後再按下 enter,就會執行安裝。

要看有沒有安裝成功,可以輸入:

firebase -V

如果有出現版本號,代表安裝成功。

登錄

安裝完 Firebase CLI,接著必須登入帳號,輸入:

firebase login

按下 enter,會問要不要將錯誤訊息回報給 Firebase,這個看個人。

接著會開啟網頁,是 Google 在問要不要授權給 Firebase,按下允許後,就會看見成功訊息:

登錄成功訊息
登錄成功訊息

終端機上也會出現一行: Success! Logged in as 你的Google帳號。告知我們是登入了哪個帳號。

要測試是不是真的登入了 Firebase,輸入:

firebase projects:list

有成功登入,就會出現終端機上秀出我們所擁有的 Firebase 專案。

登錄成功的話,會出現所擁有的專案列表
登錄成功的話,會出現所擁有的專案列表

更改成 Blaze 付費方案

開頭有說 Cloud Functions 超過免費用量後是會收費的,是屬於要付費的方案。

在開始用 Functions 之前,必須把我們的專案改成付費。

進到 Firebase 的後台,並進到我們要用 Functions 的專案,會看見專案名字的右邊有個寫著「Spark 方案」的按鈕,點擊它:

點擊方案名稱的按鈕
點擊方案名稱的按鈕

接著會出現方案選擇,預設是免費方案,為了用 Functions 必須改成付費,點擊 Blaze 下的「選取方案」:

點擊選取方案
點擊選取方案

之後 Firebase 會再次確認是否真要換付費方案,再次確認即可。

方案換成功後,Firebase 還會提醒你可以設定一個預算,要超過預算了就發通知信來:

可以設定預算快訊
可以設定預算快訊

在本機案裝 Firebase Cloud Functions

建立一個資料夾後,用終端機開機,接著輸入:

firebase init

按下 enter 後,會出現選單,選擇要在本地安裝 Firebase 的哪些功能。

因為未來的目標是可以把機器人搬到 Cloud Functions 上,所以就安裝 Firestore、Functions 這二個:

選擇要安裝哪些 Firebase 的功能
選擇要安裝哪些 Firebase 的功能

選好後,接著會出現下一個選單,選擇是要新增一個專案,還是連到現有的 Firebase 專案,Augustus 已在 Firebase 有專案可以用,因此選擇「Use an existing project」,是要新增或是用現有,就看各人:

選擇專案
選擇專案

選擇好專案後,有可能會出現一個錯誤訊息:

「Error: It looks like you haven’t used Cloud Firestore in this project before.」

因為我們在第一步有選 Firestore,如果第二步選擇了用現有專案,而那個現有專案本身在 Cloud Firestore 上沒有資料的話,就會出現這個錯誤。

解決這個錯誤很簡單,就是隨便塞幾個資料到 Cloud Firestore 上就好。

用 Javascript 塞資料的方式可以參考這篇:Firebase Cloud Firestore 常用功能筆記

那當然,也可以直接進 Firebase 後台去塞。

Init 的過程中,Firebase 還會問一些問題,全部都用預設值就行(就是一直無腦地按 enter),init 結束,會看見資料夾中多了很多檔案:

Functions 安裝成功,會看見多了很多檔案
Functions 安裝成功,會看見多了很多檔案

在 functions > index.js 的檔案中,還可以看到貼心的給了範例的程式碼。

關於各個檔案的說明可以看文件,這邊就不一一列出。


部署 Functions

我們的資料夾裡,「functions > index.js」已經寫好了一個「helloWorld」的 function,解開註解後就可以部署上 Firebase,可以直接拿來看部署上去後的改變。

解開 helloWorld 的註解
解開 helloWorld 的註解

在資料夾內打開終端機,輸入:

firebase deploy --only functions

終端機就會只部署「functions」這個資料夾的檔案上去。

部署過程中終端機都會顯示訊息,部署完整個訊息是這樣:

deploy 的訊息
deploy 的訊息

訊息裡會看到一句:

Function URL (addMessage): https://us-central1-xxxxxxxxxxx.cloudfunctions.net/helloWorld

這一句就是觸發這個 function 的 URL,開啟瀏覽器,網址列貼上這行網址,我們剛傳上去的「helloWorld」這個 function 就會被執行。

我們這邊把網址貼到瀏覽器上,看會發生什麼:

把觸發 function 的網址貼上瀏覽器
把觸發 function 的網址貼上瀏覽器

可以看見頁面上顯示了「Hello from Firebase!」。

我們看一下這個「functions > index.js」的這個檔案,在 helloWorld 裡最後寫著:

response.send("Hello from Firebase!");

沒錯,最後 Functions 會回傳「Hello from Firebase!」來。

我們進到 Firebase 的後台,然後點擊「Functions」,可以看到在資訊主頁的部份,多了一條 helloWorld 的函式,上面也有寫著觸發的 URL:

Firebase 後台可以看見 Functions 的列表
Firebase 後台可以看見 Functions 的列表

部署的 Command Line

文件:https://firebase.google.com/docs/functions/manage-functions

這邊整理一下部署檔案到 Firebase 的命令。

部署全部的 Functions:

firebase deploy --only functions

只部署 Function 裡的指定 function:

firebase deploy --only functions:helloWord,functions:helloWorld2

刪除指定的 function:

firebase functions:delete helloWorld

一次刪除多個 function:

firebase functions:delete helloWorld helloWorld2

如果是要修改 function 的名稱,就要先部署新的名稱上去,接著再刪除舊的名稱:

firebase deploy --only functions:hellowWorld_new_name

firebase functions:delete hellowWorld_old_name

本機測試 Functions

如果我們在本機開發完,可以直接在本機測試,畢竟我們可能每次都部署到 Firebase 上後才來測,部署跟測試都會耗掉免費的額度,一個不小心就會超過。

看一下資料夾的內容:

functions 的資料夾內容
functions 的資料夾內容

可以看到有「package.json」檔,Good,代表可以在本機把 Node.js 給運行起來,打開 package.json 檔,會看到「scripts」有以下內容:

"scripts": {
  "lint": "eslint .",
  "serve": "firebase emulators:start --only functions",
  "shell": "firebase functions:shell",
  "start": "npm run shell",
  "deploy": "firebase deploy --only functions",
  "logs": "firebase functions:log"
}

這些就是我們可以輸入 npm run XXXXX 的部份。

npm run serve

就會看見終端機開始執行,並把每一個流程都寫了出來,從終端機中我們就可以看見本機測試的 URL:

從訊息中可以看到本機測試的 URL
從訊息中可以看到本機測試的 URL

觸發 Functions:HTTP request

這段會寫用 HTTP request 來觸發 Functions。

其實這段在預設給的 helloWorld 就是了,這邊只是多做點補充。

Functions 是用 Node.js 在寫,因此如果本來就會 Node.js 的大大們會上手地很快。

像我們是用 Node.js + express,一般 http request 會像這樣:

app.get('/request_url', (request, response) => {
  response.send('hello World')
})

到了 Functions,就是換成它們的規則,但一樣有 request、response:

exports.functionName = functions.https.onRequest((request, response) => {
  response.send('hello World');
});

因為都是 Node.js,所以 request、response 的物件就跟 Node.js 相同,在官方文件裡放的連結也是 express 的連結。

Request:https://expressjs.com/en/api.html#req

Response:https://expressjs.com/en/api.html#res


觸發 Functions:排程

文件:https://firebase.google.com/docs/functions/schedule-functions

除了藉由 HTTP request 來觸發外,也可以寫排程來自動觸發。

要注意的是,文件上說「每個 Cloud Scheduler 作業每月的費用為 $ 0.10(USD)」、「每個 Google 帳戶可以提供三個免費作業」,所以想要免費使用的話,排程的部份不要設定超過三個。

另外,排程這段 Augustus 一直想在本機測,卻一直失敗,PubSub emulator 這功能一直 On 不起來,還請高手們有成功在本機測試排程這段的,留言提供解法,感謝~

寫排程的 Functions 如下:

exports.scheduledFunction = functions.pubsub.schedule('*/5 * * * *').onRun((context) => {
  console.log('每 5 分鐘觸發一次');
  return null;
});

functions.pubsub.schedule 要包的是時間設定,這部份的教學可看這篇:Nodejs 定時執行(node-cron)

部署上去後,就會看見 Firebase 後台多了一個觸發條件是時間:

新增了排程的觸發條件
新增了排程的觸發條件

那要看有沒有運行成功,可以在「紀錄」那邊觀看。


觸發 Functions:Callable

Callable 是我們在前端的頁面上主動去觸發 Fucntions。

要觸發 Functions,在前端頁面要引用 Firebase SDK。

Callable Functions 的範例程式碼:

exports.callable_name = functions.https.onCall((data, context) => {
  // data:前端傳來的資料
  // context:非必填,為使用者的資料
});

如果前端頁面上,使用者有用 Firebase Auth 登入,context 就會是使用者的登入資料,如果未登入 context 就會是 null。

另外,因為引用 Firebase SDK 時,initialize 的 config 設定全部指定的都是 Firebase 的 URL,所以在呼叫 Callable Functions 時,也會是觸發 Firebase 上的,無法在本機上做測試。

前端頁面上觸發 Callable 的程式碼,這邊包含用 Firebase 中,用 Google 登入的部份,Firebase 後台中的 Authentication 要打開 Google 登入的功能,如果沒開也沒關係,把下方程式碼中有關「登入」、「登出」的部份給刪掉就好。


觸發 Functions:Firebase Auth

文件:https://firebase.google.com/docs/functions/auth-events

頁面有使用 Firebase Auth 的話,當使用者註冊帳號、刪除帳號,也可以觸發 Functions。

註冊帳號

刪除帳號

這二個 callback 回來的 user,有的資料如文件:https://firebase.google.com/docs/reference/admin/node/admin.auth.UserRecord.html


Functions 讀寫刪 Firestore 資料

「functions > index.js」檔案中,再引用 firebase-admin 後就可以讀寫 Firestore 的資料。

關於 Firestore 讀、寫、刪的方法,請見這篇筆記:Firebase Cloud Firestore 常用功能筆記


Functions 回傳錯誤訊息

當遇到錯誤時,可以指定遇到什麼錯誤就回傳什麼錯誤訊息,報錯方式如下:

new functions.https.HttpsError(錯誤碼, 要回的訊息)

錯誤碼請看文件:https://github.com/grpc/grpc/blob/master/doc/statuscodes.md

使用範例:

Summary
Firebase Cloud Functions 基本使用筆記
Article Name
Firebase Cloud Functions 基本使用筆記
Description
本篇大綱:本篇要解決的問題。安裝 Firebase CLI。在本機案裝 Firebase Cloud Functions。部署 Functions。本機測試。觸發:HTTP、排程、Callable。觸發:Firebase Auth。讀寫刪 Firestore 資料。回傳錯誤訊息。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg
訂閱
通知
guest
0 Comments
Inline Feedbacks
看所有留言