JavaScript >> Javascript 文檔 >  >> Vue.js

使用 Vue.js 和 Firebase 雲函數實現無服務器

歡迎來到 Vue.js 基礎的 Fire 的新一集!系列。

在這一集中,我將把我們的 Vue.js Notes Writer 應用程序與無服務器後端——特別是 Firebase Cloud Functions 集成。

如果您還沒有閱讀本系列的其他部分,我強烈建議您在開始閱讀之前閱讀。

從這個角度看海市蜃樓!
使用 Vue.js 將筆記存儲在 Cloud Firestore 中
Vue.js 中用於用戶身份驗證的 Firebase

要跟進本文的演示部分,您可以使用此 GitHub 源代碼倉庫作為起點。

Firebase 雲函數,概念

Cloud Functions 是 Google Cloud Platform 的一部分。您可以使用它們來編寫和部署可以響應來自 Google Cloud 服務的事件的代碼,包括但不限於 Firebase 系列產品。

借助 Cloud Functions,您可以使用不同的產品拼湊您的應用程序。例如,用戶通過 Web 應用在 Firestore 中創建一個新文檔。因此,雲函數會觸發並響應文檔創建事件。 Cloud Function 的邏輯完全取決於您正在實現的業務場景。

它們不僅可以讓您將 Google Cloud 服務連接在一起,還可以讓您創建自己的一組 REST API 以在您的 Web 或移動應用程序中使用。

Cloud Functions 項目是 Google Cloud 項目之上的一個包裝器。但是,它更便於開發人員配置和使用。

Cloud Functions 提供的兩大優勢: 以安全的方式將您的代碼集中在 Google Cloud 服務器上。 Firebase Cloud Functions 在 Google 服務器上運行。您的所有應用程序,無論是 Web、移動還是桌面應用程序,都可以訪問和使用它們。代碼安全。最好將 Firebase 服務的訪問代碼和密鑰保存在後端(在 Google 服務器上),而不是將它們暴露在客戶端應用代碼中。

Cloud Functions 最適合用於:觸發代碼以響應來自 Firebase 產品的事件。執行寫入實時數據庫和 FirestoreUpload 到您的 Cloud Storage 存儲分區。響應在 Firebase 身份驗證中創建的新帳戶。處理傳入的 HTTPs 請求。

Firebase 支持兩種風格的 Cloud Functions:HTTPs 觸發的 FunctionsBackground 觸發的 Functions

與 Google Cloud Functions 不同,Firebase Cloud Functions 僅支持帶有 Node.js 的 JavaScript/TypeScript。該團隊正在努力包括更多的編程語言。在那之前,讓我們盡情享受 JavaScript!

HTTPs 觸發的雲函數

讓我們來剖析一下用於 HTTPs 觸發器的 Cloud Functions。

首先確保您的機器上安裝了 Node.js 版本>=8.13.0。

接下來,通過運行以下命令在您的計算機上全局安裝 Firebase CLI:

npm install -g firebase-tools

通過運行以下命令創建一個 Firebase 項目:

mkdir firebase-functions-http
cd firebase-functions-http

下一步是登錄 Firebase 服務以連接新項目。發出這個:

firebase login

該命令會在您的默認瀏覽器中打開一個新選項卡,以請求 Firebase 帳戶所需的一些權限。

讓我們通過運行以下命令來初始化 Firebase 項目:

firebase init

此命令將引導您通過命令行嚮導選擇要添加到項目中的 Firebase 功能。

對於我們的案例,讓我們選擇以下內容:

您要為此文件夾設置哪些 Firebase CLI 功能? 函數

您想使用哪種語言來編寫 Cloud Functions? JavaScript

您想使用 ESLint 來捕獲可能的錯誤並強制執行樣式嗎? 是的

您想現在使用 npm 安裝依賴項嗎? 是的

就是這樣!

Firebase CLI 做項目腳手架,準備好項目文件。

該命令搭建一個 Node.js 項目,並將 Cloud Function 相關代碼存儲在 /functions 中 文件夾。

/functions.package.json 列出 Cloud Function 所需的所有依賴項。最重要的依賴是:

"dependencies": {
    "firebase-admin": "^8.9.2",
    "firebase-functions": "^3.3.0"
  },

讓我們通過運行以下命令來確保我們擁有這些軟件包的最新版本:

npm install firebase-admin@latest firebase-functions@latest

/functions/index.js 文件包含雲函數代碼。

const functions = require('firebase-functions');

exports.helloWorld = functions.https.onRequest((request, response) => {
    response.send("Hello from Firebase!");
});

index.js 文件是一個典型的 Node.js 模塊文件,它導出一個名為 helloWorld 的雲函數 .您可以根據需要導出更多功能。

該模塊首先需要 firebase-functions 圖書館。該庫允許您為 HTTPs 觸發器創建 Cloud Functions。它暴露了 onRequest() 功能。這個函數需要兩個參數,RequestResponse 對象。回調函數需要通過調用 response.send() 來返回 Promise 功能。

Node.js 的流行 Express.js 模塊位於 Cloud Function for HTTPS 觸發器的後面。當您在 Firebase 上部署 Cloud Function 時,它會在後台創建一個 Express.js 應用。此應用將偵聽 /helloWorld 的任何 HTTPs 請求 ,準備一個RequestResponse 對象,並將通過您的 Cloud Function 調用,將其傳遞給兩個對象。

您可以在 onRequest() 中包含任何代碼 回調函數,就像您在編寫 Express.js 應用程序時所做的那樣。

讓我們通過發出以下命令在本地運行此 Cloud Function:

firebase serve --only functions

該命令啟動 Firebase Cloud Functions 模擬器,以允許您在本地運行該函數,而無需將其部署到 Firebase 服務器。

✔ functions: Using node@10 from host.
✔ functions: Emulator started at http://localhost:5000
i functions: Watching "/.../firebase-functions-http/functions" for Cloud Functions...
✔ functions[helloWorld]: http function initialized (http://localhost:5000/firebase-functions-http/us-central1/helloWorld).

將函數 URL 複製並粘貼到瀏覽器中,您將看到 Hello from Firebase! 的純文本響應 .

要將 Cloud Function 部署到 Firebase 平台,請運行以下命令:

firebase deploy --only functions

在 Cloud Function for HTTPs 觸發器中,您可以調用任何其他第三方服務。例如,您可以查詢 Firestore 數據庫並從中返回數據。

後台觸發的雲函數

後台觸發函數是 Firebase 提供和支持的另一類函數。

Firebase 系列中的每個產品都公開了一組事件,這些事件會在特定操作時觸發。

例如,當在 Firestore 中創建一個新文檔時,OnCreate 事件被觸發。

另一個例子是在 Firebase 身份驗證模塊中創建新用戶時,onCreate 事件被觸發。

exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
  // ...
});

函數 對象提供對所有受支持類型的 Cloud Functions 的訪問權限。這包括 HTTP 和後台觸發的。

上面的示例使您可以訪問已創建的用戶。然後,您可能決定向用戶發送電子郵件,或將通知推送到應用程序。天空才是極限!!

Firebase Cloud Functions 支持所有 Firebase 產品,讓開發人員有機會處理由它們觸發的許多事件。

Firebase Cloud Functions 文檔是完整的,對學習所有細節非常有幫助。因此,事不宜遲,讓我們進入Notes App Writer,並添加一個新的後台觸發雲功能。

演示

add-auth 克隆 Notes App Writer 分支。這是我們在上一篇文章中對應用中的用戶進行身份驗證時所做的分支。

克隆應用

運行以下命令克隆分支:

git clone --single-branch --branch add-auth [email protected]:bhaidar/notes-writer.git

確保通過運行以下命令安裝所有 NPM 包:

npm install

添加對 Firebase Cloud Functions 的支持

如果您之前沒有登錄過 Firebase,那麼是時候運行以下命令了:

firebase login

登錄後,讓我們再次初始化 Firebase 服務,以便這次包含 Functions。

firebase init

遵循 HTTPs 觸發的雲函數 中提到的相同步驟 部分。

您會注意到在項目的根文件夾下創建了一個名為 functions 的新文件夾 .正如您現在所知道的,此文件夾包含您項目中 Cloud Functions 的所有源代碼。

每當您在項目中添加對 Cloud Functions 的支持時,通過運行以下命令來更新 Firebase NPM 包總是很重要的:

npm install firebase-admin@latest firebase-functions@latest

使用環境變量存儲配置設置

讓我們重溫一下 /firebaseConfig.js 文件。此文件包含 Firebase 控制台提供的 Firebase 連接設置。

我將使用 Vue.js CLI v3 中的隱藏 gem,它允許您在應用程序中使用環境變量來存儲此類配置設置。事實上,這是在 Vue.js 應用程序中存儲配置設置的推薦方式,而不是將它們放在純 JSON 或 JavaScript 文件中。

上面引用的 CLI 文檔為您提供了有關在您的應用程序中使用的環境變量文件的所有詳細信息。現在,創建一個新的 .env 項目根目錄下的文件,並粘貼以下鍵:

VUE_APP_API_KEY=
VUE_APP_KEY_AUTH_DOMAIN=
VUE_APP_KEY_DATABASE_URL=
VUE_APP_PROJECT_ID=
VUE_APP_STORAGE_BUCKET=
VUE_APP_MESSAGING_SENDER_ID=
VUE_APP_ID=

從 Firebase 控制台獲取實際密鑰並將它們放在 == 之後 在每一行簽名。

例如,

VUE_APP_PROJECT_ID=notes-writer-f1e85

回到 firebaseConfig.js 文件,將其內容替換為以下內容:

import firebase from 'firebase/app'
import 'firebase/firestore'
import 'firebase/auth'

// firebase init
const config = {
  apiKey: process.env.VUE_APP_API_KEY,
  authDomain: process.env.VUE_APP_KEY_AUTH_DOMAIN,
  databaseURL: process.env.VUE_APP_KEY_DATABASE_URL,
  projectId: process.env.VUE_APP_PROJECT_ID,
  storageBucket: process.env.VUE_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.VUE_APP_MESSAGING_SENDER_ID,
  appId: process.env.VUE_APP_ID
}

firebase.initializeApp(config)

// firebase db
const db = firebase.firestore()

// firebase auth
const auth = firebase.auth()

// firebase collections
const notesCollection = db.collection('notes')

export {
  auth,
  db,
  firebase,
  notesCollection
}

實現雲功能

讓我們訪問 functions/index.js 文件,開始實現我們的功能邏輯。

此功能的目的是監聽在 Firestore 中創建的任何新 Note Document,獲取其詳細信息,然後通過電子郵件發送。

替換index.js的內容 文件包含以下內容:

const functions = require('firebase-functions')
const admin = require('firebase-admin')

admin.initializeApp()

exports.onNewNoteCreated =
  functions.firestore.document('notes/{notesId}').onCreate((snap, context) => {
    const { body } = snap.data()
    const { params: { notesId } } = context

    console.log(context)
    console.log(body)
    console.log(notesId)

    return Promise.resolve(true)
  })

JavaScript 模塊會導入 Firebase Functions Admin SDK 庫。

該模塊公開了一個名為 onNewNoteCreated 的雲函數 .此函數訂閱 OnCreate() 創建新的 Firestore 文檔後運行的事件處理程序。

onCreate() 事件處理程序接受具有兩個參數的回調函數:DocumentSnapshot.EventContext。

前一個參數可以讓您訪問創建的 Document 的內容,而後者可以讓您訪問事件發生的上下文。

下一行提取 body 票據文件的財產。然後,代碼提取 notesId 來自 EventContext 參數。

然後將變量記錄到 Cloud Functions Logs 數據庫。根據我的經驗,Cloud Functions Logs 是調試和測試函數的最佳工具!

最後,該函數返回一個已解決的 Promise。我將在本文的下一節進一步討論從 Cloud Functions 返回 Promise 的概念。

讓我們先使用 Firebase Functions Shell 在本地運行 Cloud Function。

運行以下命令:

firebase functions:shell

您使用 Functions Shell 以交互方式測試您的函數。您可以通過以下鏈接了解更多信息:以交互方式測試函數

在幕後,Shell 會加載 Functions 模擬器,並將它們全部列出以供參考。

要執行單個函數,只需在 firebase 上運行以下命令 命令行:

onNewNoteCreated({ body: "Hello Firebase Functions!" }, { params: { notesId: "note-#001" }})

回車!

輸出如下:

'Successfully invoked function.'

firebase > >  

{ eventId: 'c6f8eec2-e7e0-463e-9966-c8c8b0a25505',
> timestamp: '2020-02-15T08:12:02.088Z',
> eventType: 'google.firestore.document.create',
> resource:
> { service: 'firestore.googleapis.com',
> name:
> 'projects/notes-writer-f1s85/databases/(default)/documents/notes/note-#001' },
> params: { notesId: 'note-#001' } }

> Hello Firebase Functions!

> note-#001

第一個文本塊代表 ExecutionContext 目的。它為您提供有關當前事件及其上下文的詳細信息。例如,事件類型是 google.firestore.document.create .新文檔的完整路徑顯示在 resource 內 財產。最後,您的 Cloud Function 可以訪問 params 包含新 Notes 文檔 ID 的屬性。

第二個文本塊打印 body 新的筆記文件。

最後,第三個文本塊打印出 notesIdparams 抓取 ExecutionContext 上的屬性 對象。

在 Cloud Function 中發送電子郵件

讓我們的雲功能更有用!使用 Firebase 系列產品,您有多種選擇。

例如,我們可以使用 Firebase Cloud Messaging 產品將新 Note 作為推送通知發送。但是,我不想在一篇文章中介紹多個 Firebase 產品。

相反,讓我們使用電子郵件發送新 Note Document 的內容。為此,我們需要安裝一個額外的 NPM 包以允許我們發送電子郵件。

確保您在 /functions 內 文件夾,運行以下命令:

npm install nodemailer

我們將使用 nodemailer Node.js 模塊來發送電子郵件。

替換/functions/index.js的內容 使用以下代碼:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const nodemailer = require('nodemailer')

admin.initializeApp()

var transporter = nodemailer.createTransport({
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: '',
    pass: ''
  }
})

exports.onNewNoteCreated =
  functions.firestore.document('notes/{notesId}').onCreate((snap, context) => {
    const { body } = snap.data()
    const { params: { notesId } } = context

    console.log(body)
    console.log(notesId)

    const mailOptions = {
      from: '',
      to: '',
      subject: 'A new note is created',
      html: `
        <h1>New Note</h1>
        <p>A new note is created with the following details:</p>
        <p>
          Note Id: <br />
          ${notesId}
        </p>
        <p>
          Note Body: <br />
          ${body}
        </p>`
    }

    return transporter.sendMail(mailOptions)
      .then(() => console.log('Email Sent!'))
      .catch(error => console.error(error))
  })

首先導入 nodemailer 圖書館。

然後,創建一個 nodemailer 傳輸器。傳輸者是負責發送電子郵件的對象。 Nodemailer 模塊支持基於 SMTP 的傳輸和其他非基於 SMTP 的傳輸。我會保持簡單,並為此 Cloud Function 使用 SMTP 傳輸。

為此,您需要使用 SMTP 帳戶創建一個新的 Nodemailer Transport。我將使用 GMAIL SMTP 帳戶詳細信息。這可以在本地測試,但從不 用於生產。用於生產的其他選項包括:您從託管公司獲得的 GMAIL OAUTH 2 和 SMTP 帳戶。

替換用戶 並且通過 具有真實 Gmail 帳戶的字段。

在 Cloud Function 內部,準備一個 mailOptions 包含要發送的電子郵件的所有詳細信息的對象。確保包含 from , ,以及其他字段。

最後,通過返回 transporter.sendMail(mailOptions) 發送電子郵件 函數調用。這個函數返回一個 Promise。

而已!您可以按照上述步驟使用 Functions Shell 在本地測試函數。

讓我們將 Cloud Function 部署到 Firebase,然後開始接收電子郵件!

firebase deploy --only functions

上面的命令會在您當前的應用程序中部署所有 Cloud Functions。

現在,每當您在應用程序中創建新筆記時,onNewNoteCreated() Cloud Function 被觸發,最終您會收到一封類似如下的電子郵件:

雲函數執行流程

Firebase 在內部管理服務器以及部署和運行雲函數所需的所有資源。雲函數執行完畢後,需要清理函數使用的資源。

Firebase 如何判斷或決定現在是清理資源的正確時間,以及 Cloud Function 已完成執行?

這個任務肯定更複雜!為什麼?

您將編寫的大部分 Cloud Functions 代碼都將與其他 Firebase SDK 甚至第三方 SDK 進行交互。這種類型的通信是異步發生的。

雲函數執行代碼並立即返回。但是,可能會有某種異步工作在後台掛起。因此,Firebase 不能只運行該函數,並清理所有資源。它必須等到函數完全運行完畢,然後再執行。

因此,所有 Firebase SDK 都支持 JavaScript Promises。什麼是 JavaScript Promise?

Promise 代表一些最終應該完成的異步工作!當 Promise 跟踪的工作仍在執行時,Promise 處於掛起狀態。如果工作成功完成,則稱 Promise 已完成。如果有錯誤,則承諾被拒絕。

這些是 Promise 可以通過的唯一狀態。一旦完成或拒絕,Promise 將無法返回任何其他狀態。

例如,當您的代碼:從數據庫讀取或寫入時,Firebase Admin SDK 會返回 Promise。與雲存儲中的文件交互。使用雲消息傳遞通知。

因此,在處理後台觸發的雲函數時,return 非常重要 您在 Cloud Function 中執行的 Firebase SDK API 調用。 Cloud Function Runner 現在可以訪問 Promise。只要 Promise 處於掛起狀態,它就會等待,不會採取任何行動。一旦 Promise 被履行或被拒絕,它就可以安全地移除所有資源,並進行清理。

對於 HTTPS 觸發的雲函數,請始終確保返回 response.send() 作為代碼的最後一行。只有當函數向客戶端返迴響應時,Cloud Functions Runner 才會終止並清理由 HTTPs 觸發的函數。

在本文中,我展示瞭如何集成和使用第三方庫 Nodemailer。我們實現的是一個後台觸發函數,因此我們需要在函數結束時返回一個 Promise。我們是怎麼做到的?

return transporter.sendMail(mailOptions)
      .then(() => console.log('Email Sent!'))
      .catch(error => console.error(error))
  })

sendMail() 函數發送一封電子郵件,並返回一個 Promise。在我們的例子中,我們發送一個 Email Sent! 當 Promise 完成時向日誌發送消息。此外,當 Promise 被拒絕時,我們會記錄任何錯誤。同時,我們返回 sendMail() Promise,讓 Cloud Functions Runner 使用該 Promise 清理此函數的資源。這只適用於 JavaScript Promises 是可鏈接的!

結論

目前,這將是 Fire the base of Vue.js 的最後一集!系列。

Firebase 是一個很大的話題,需要很多文章才能涵蓋所有內容。 Firebase 的團隊在提供體面的文檔方面做得很好。不過,我相信,使用 Firebase SDK 會給您帶來理論無法獲得的經驗和知識。

將來,我可能會在這個系列中添加劇集。然而,在接下來的兩週內,我將開始一個關於 Vue.js 開發的新系列。敬請期待!

Vueing 快樂!


Tutorial JavaScript 教程
  1. 在反應應用程序上更改文檔標題

  2. 在 React 組件之間交換事件

  3. 將您的 Django + React.js 應用程序部署到 Heroku

  4. Javascript 內聯 onclick 轉到本地錨點

  5. 沒有 ifs……JavaScript 中語句分支的替代方案

  6. 使用 push() 和 unshift() 將項目添加到數組

  7. 黑客了解您的財務狀況 (KYF) - 第 0 部分設置

  1. Vue Firebase UI:創建登錄頁面 [Facebook/Google Auth]

  2. Vue.js 內置的支持 iTunes 音頻的搜索

  3. 🚀 GitHub 上面向 Web 開發人員的 10 個熱門項目 - 2021 年 11 月 5 日

  4. 如何計算字符串中出現的字符串?

  5. 一步一步的 React、NodejS 和 MySQL 簡單的全棧應用程序 2018(部分:6)

  6. 如何使用兩個按鈕正確切換兩個元素?

  7. 在 Antd 和 CRA 中使用 sass

  1. CSS 變量,但帶有一些 JavaScript。 ✨

  2. 在 html 頁面上的 AJAX 調用期間附加的額外元素

  3. 使用 MongoDB Atlas 和 MERN 添加全文搜索

  4. 在您的 Vue 應用程序中嵌入 dev.to 文章