{%hackmd @wh91008/theme %} # Lecture 5 - Cloud Function的入門與部署(Node.js) ###### tags: `GCP` `Firestore` `Cloud Function` `Node.js` [TOC] --- ## ==一、什麼是Cloud Function?== Google Cloud Functions 是一個可以建置並連結多個雲端服務的無伺服器執行環境。透過 Cloud Functions,您可以將那些簡單且單一的功能附加在從您雲端基礎設施/服務送出的 events 上。當 event 發生的時候,Cloud Functions 會被啟動,您的程式碼將被執行在一個完全代管的環境下,您不必額外設定基礎設施或是擔心要管理伺服器了。 ###### :book: 資料來源:https://blog.gcp.expert/cloud-functions-introduction/ --- ## ==二、工具需求== 本文主要是先建置Firebase的開發環境,需要安裝的工具為: - Python(事先安裝) - Sublime/VS Code/Pycharm...等任何可用來編譯JavaScript的程式編輯器(事先安裝) - Node.js(本文會解說) - npm(本文會解說) - Firebase CLI(本文會解說) --- ## ==三、入門與部署== 首先為了將python與Cloud Function能夠同步,必須先部署和編寫第一個函數,在此使用Node.js來製作第一個函式,完成的結果會如下圖: ![](https://i.imgur.com/XvQ6li7.png) :::warning :bulb: 備註:根據 [官方訊息](https://firebase.google.com/docs/functions/manage-functions) ,Node.js 8(自2020年6月8日起不推薦使用)且將在2021年3月15日之後停止執行,目前已全面更換為 Node.js 10 ,在這個版本要使用 Cloud Function 一定需要綁定信用卡/金融卡,**啟用 Blaze 即用即付計費計劃,否則不能使用。** ::: ### 第一步:創建Firebase項目 創建方式,請參照第一章,或者直接在 Firestore 的控制台中單擊“ 添加項目”,然後選擇或輸入項目名稱。 ### 第二步:設置Node.js和Firebase CLI 需要的東西為:Node.js、npm與Firebase CLI - **安裝Node.js** - 將函數部署到Cloud Functions運行時,官方建議使用Node.js 8進行入門。 - NPM 是附屬在 Node.js 中的套件管理工具,我們在安裝 Node.js 時,就可以順便將 NPM 安裝到電腦中,並且在命令列 / 終端機模式中使用。 安裝教學可參照 [影片](https://www.youtube.com/watch?v=SYQU0TSMjYw) ,想安裝可前往 [Node.js官網](https://nodejs.org/zh-tw/download/) - **通過npm安裝Firebase CLI** ```npm install -g firebase-tools``` 安裝Node.js和npm後,於開始功能表搜尋npm並開啟後,輸入上述指令即可安裝Firebase CLI Firebase CLI安裝的成功與否,將會嚴重後續可使用的所有與Firebase有關的命令。如果安裝成功(沒有出現錯誤訊息),則不需理會以下指令。 - 如果命令失敗,可能需要更改npm權限。 更改方式可參照 [網址](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally) - 要更新到最新版本firebase-tools,則於npm執行 ``` npm install firebase-functions@latest firebase-admin@latest --save npm install -g firebase-tools ``` ### 第三步:初始化Firebase SDK for Cloud Functions 要初始化您的項目: - 執行```firebase login```,用來透過瀏覽器登錄並驗證firebase工具。登入了Gmail之後瀏覽器就會得到下列圖示,代表登入已成功: ![](https://i.imgur.com/EMtFzCN.png) - 轉到Firebase項目目錄。(即於npm更改路徑至原先儲存firebase.json的位置) - 執行```firebase init functions```,此工具提供使用npm安裝的各種選項。(第一次使用通常為Y按到底) - 且該工具提供兩種語言支持選項(本教程選擇JavaScript): - JavaScript - TypeScript。 成功完成這些命令後,項目結構如下所示: ``` myproject +- .firebaserc # Hidden file that helps you quickly switch between | # projects with `firebase use` | +- firebase.json # Describes properties for your project | +- functions/ # Directory containing all your functions code | +- .eslintrc.json # Optional file containing rules for JavaScript linting. | +- package.json # npm package file describing your Cloud Functions code | +- index.js # main source file for your Cloud Functions code | +- node_modules/ # directory where your dependencies (declared in # package.json) are installed ``` 代表你所在的路徑下,應該擁有: 文件```.firebaserc```、```firebase.json```,與資料夾```functions```。 且資料夾```functions```中,又含有: 文件```.eslintrc.json```、```package.json```、```index.js```與資料夾```node_modules``` ### 第四步:導入所需的模塊並初始化應用程序 完成上述步驟後,打開上述的```index.js```文件,並且將文件內容添加/更改如下: ```javascript= // [START all] // [START import] // The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers. const functions = require('firebase-functions'); // The Firebase Admin SDK to access the Firebase Realtime Database. const admin = require('firebase-admin'); admin.initializeApp(); // [END import] ``` ### 第五步:添加addMessage()功能 - ```addMessage()```是用來產生一個能寫入及時資料庫的URL 一樣將下列程式碼接續於```index.js```文件中 ```javascript= // [START addMessage] // Take the text parameter passed to this HTTP endpoint and insert it into the // Realtime Database under the path /messages/:pushId/original // [START addMessageTrigger] exports.addMessage = functions.https.onRequest(async (req, res) => { // [END addMessageTrigger] // Grab the text parameter. const original = req.query.text; // [START adminSdkPush] // Push the new message into the Realtime Database using the Firebase Admin SDK. const snapshot = await admin.database().ref('/messages').push({original: original}); // Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console. res.redirect(303, snapshot.ref.toString()); // [END adminSdkPush] }); // [END addMessage] ``` ### 第六步:部署並執行 addMessage() - 開啟剛剛的npm,並且執行命令: ```firebase deploy --only functions``` - 執行上述命令之後,Firebase CLI就會輸出有HTTP功能端點的URL。因此在npm中將會看到: ``` Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage ``` :::warning :bulb:小提醒:有可能在執行此步驟結束後發現並沒有產生URL,此時則執行```firebase use --add```,並且選擇專案名稱,取該專案的別稱,即可解決。 ```javascript= C:\Users\lumia\functions> ? Which project do you want to add? fir-test-84116 ? What alias do you want to use for this project? (e.g. staging) Firebase-test-cloud ``` ::: - 將網址尾端加上 ```?text=uppercaseme``` ,得到網址如下: ``` https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercaseme ``` - 貼入瀏覽器即可得到下述介面 :::warning :bulb: 小提醒:如果一開始建置Database時是選擇讓Database公開,則會多出一串提醒為「您的安全性規則定義為公開,因此任何人都能竊取、修改或刪除資料庫中的資料。」 ::: ![](https://i.imgur.com/1LTzbPD.png) 接著選取Functions就能看見已經成功部署如下: ![](https://i.imgur.com/XvQ6li7.png) - 建立觸發條件為HTTP的Python函式: 進入以下網址 https://cloud.google.com/python/?refresh=1&pli=1 ![](https://i.imgur.com/Td3JRdk.png) - 點擊設定專案並且選擇所要部署的專案 - 選取建立函式並且把執行階段選取python3.7(可將原先系統預設的程式碼更新為自己所需要的程式碼) - 即可得到觸發條件為HTTP格式的Python函式 ![](https://i.imgur.com/sKgkZUC.png) ### 第七步:添加makeUppercase()功能 - ```makeUppercase()```是用來在即時數據庫寫入時觸發並將文本轉換為大寫。 一樣將下列程式碼接續於index.js文件中: ```javascript= // [START makeUppercase] // Listens for new messages added to /messages/:pushId/original and creates an // uppercase version of the message to /messages/:pushId/uppercase exports.makeUppercase = functions.database.ref('/messages/{pushId}/original') .onCreate((snapshot, context) => { // Grab the current value of what was written to the Realtime Database. const original = snapshot.val(); console.log('Uppercasing', context.params.pushId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to the Firebase Realtime Database. // Setting an "uppercase" sibling in the Realtime Database returns a Promise. return snapshot.ref.parent.child('uppercase').set(uppercase); }); // [END makeUppercase] // [END all] ``` ### 第八步:部署並執行 makeUppercase() - 開啟剛剛的npm,並且執行命令: ```firebase deploy --only functions``` - 使用第六步所得出的網址,尾端加上```too``` ``` https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo ``` ![](https://i.imgur.com/aea43oY.png) ###### :book: 詳細介紹可參考官方教學: ###### 1. 文字介紹: https://firebase.google.com/docs/functions/get-started?authuser=0 ###### 2. 影片介紹: https://www.youtube.com/watch?v=DYfP-UIKxH0