ph.zeng
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    {%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

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully