使用 Vue.js 和 Firestore 落地運行

已發表: 2022-03-10
快速總結 ↬構建 MVP 就是在短時間內構建大量功能。 Vue.js 是一個不錯的選擇,它具有最少的架構樣板和大量的原始功能。 它所需要的只是存儲數據的地方。

Google Firebase 有一種新的數據存儲可能性,稱為“Firestore”(目前處於測試階段),它建立在Firebase 實時數據庫的成功基礎上,但增加了一些漂亮的功能。 在本文中,我們將使用 Vue.js 和 Firestore 設置 Web 應用程序的基礎知識。

假設您有一個新產品的好主意(例如下一個 Twitter、Facebook 或 Instagram,因為我們永遠不會有太多的社交,對吧?)。 首先,您想製作該產品的原型或最小可行產品 ( MVP )。 目標是盡可能快地構建應用程序的核心,以便您可以將其展示給用戶並獲得反饋並分析使用情況。 重點是開發速度和快速迭代。

但在我們開始構建之前,我們驚人的產品需要一個名字。 讓我們稱之為“Amazeballs”。 這將是一個傳奇——等待它——膽小

這是我設想的一個鏡頭:

Amazeballs 應用截圖
傳奇的 Amazeballs 應用程序

我們的 Amazeballs 應用程序——當然——都是關於在所謂的 Balls 中與朋友分享你個人生活中的俗氣的花絮。 頂部是發布球的表格,下方是您朋友的球。

在構建 MVP 時,您需要能夠快速實現關鍵功能以及稍後快速添加和更改功能的靈活性的工具。 我的選擇落在 Vue.js 上,因為它是一個 Javascript 渲染框架,由 Firebase 套件(由 Google 提供)及其新的名為 Firestore 的實時數據庫提供支持。

跳躍後更多! 繼續往下看↓

Firestore 可以使用普通的 HTTP 方法直接訪問,這使其成為一個完整的後端即服務解決方案,您無需管理自己的任何服務器,但仍可在線存儲數據。

聽起來強大而令人生畏,但毫不費力,我將指導您完成創建和託管這個新 Web 應用程序的步驟。 注意此頁面上的滾動條有多大; 沒有大量的步驟。 此外,如果您想知道將每個代碼片段放在代碼存儲庫中的哪個位置,您可以在 github 上查看完整運行的 Amazeballs 版本。

開始吧

我們從 Vue.js 開始。 這對 Javascript 初學者來說非常棒,因為您從 HTML 開始並逐漸向其中添加邏輯。 但不要低估; 它包含許多強大的功能。 這種組合使其成為我作為前端框架的首選。

Vue.js 有一個用於搭建項目的命令行界面 (CLI)。 我們將使用它來快速進行基本設置。 首先,安裝 CLI,然後使用它基於“webpack-simple”模板創建一個新項目。

 npm install -g vue-cli vue init webpack-simple amazeballs

如果您按照屏幕上的步驟( npm installnpm run dev )打開一個帶有大 Vue.js 徽標的瀏覽器。

恭喜! 那很簡單。

接下來,我們需要創建一個 Firebase 項目。 前往 https://console.firebase.google.com/ 並創建一個項目。 一個項目以免費的 Spark 計劃開始,它為您提供有限的數據庫(1 GB 數據,每天 50K 讀取)和 1 GB 託管。 這對於我們的 MVP 來說綽綽有餘,並且在應用程序獲得關注時可以輕鬆升級。

單擊“將 Firebase 添加到您的網絡應用程序”以顯示您需要的配置。 我們將在我們的應用程序中使用這個配置,但是以一種很好的 Vue.js 方式使用共享狀態。

首先npm install firebase ,然後創建一個名為src/store.js的文件。 這是我們要放置共享狀態的位置,以便每個 Vue.js 組件都可以獨立於組件樹訪問它。 以下是文件的內容。 該狀態目前僅包含一些佔位符。

 import Vue from 'vue'; import firebase from 'firebase/app'; import 'firebase/firestore'; // Initialize Firebase, copy this from the cloud console // Or use mine :) var config = { apiKey: "AIzaSyDlRxHKYbuCOW25uCEN2mnAAgnholag8tU", authDomain: "amazeballs-by-q42.firebaseapp.com", databaseURL: "https://amazeballs-by-q42.firebaseio.com", projectId: "amazeballs-by-q42", storageBucket: "amazeballs-by-q42.appspot.com", messagingSenderId: "972553621573" }; firebase.initializeApp(config); // The shared state object that any vue component can get access to. // Has some placeholders that we'll use further on! export const store = { ballsInFeed: null, currentUser: null, writeBall: (message) => console.log(message) };

現在我們將添加 Firebase 部件。 從 Firestore 獲取數據的一段代碼:

 // a reference to the Balls collection const ballsCollection = firebase.firestore() .collection('balls'); // onSnapshot is executed every time the data // in the underlying firestore collection changes // It will get passed an array of references to // the documents that match your query ballsCollection .onSnapshot((ballsRef) => { const balls = []; ballsRef.forEach((doc) => { const ball = doc.data(); ball.id = doc.id; balls.push(ball); }); store.ballsInFeed = balls; });

然後將writeBall函數替換為實際執行寫入的函數:

 writeBall: (message) => ballsCollection.add({ createdOn: new Date(), author: store.currentUser, message })

注意兩者是如何完全解耦的。 當您插入集合時,會觸發onSnapshot ,因為您插入了一個項目。 這使得狀態管理變得更加容易。

現在你有了一個任何 Vue.js 組件都可以輕鬆訪問的共享狀態對象。 讓我們好好利用它。

發布東西!

首先,讓我們找出當前用戶是誰。

Firebase 具有身份驗證 API,可幫助您完成了解用戶的繁瑣工作。 在AuthenticationSign In Method的 Firebase 控制台上啟用相應的選項。 現在,我將使用 Google 登錄 - 帶有一個非常不花哨的按鈕。

使用 Google 身份驗證的登錄頁面截圖
使用 Google 登錄進行身份驗證

Firebase 沒有為您提供任何界面幫助,因此您必須創建自己的“使用 Google/Facebook/Twitter 登錄”按鈕和/或用戶名/密碼輸入字段。 您的登錄組件可能看起來像這樣:

 <template> <div> <button @click.prevent="signInWithGoogle">Log in with Google</button> </div> </template> <script> import firebase from 'firebase/app'; import 'firebase/auth'; export default { methods: { signInWithGoogle() { var provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider); } } } </script>

現在還有一個登錄難題,那就是在商店中獲取currentUser變量。 將這些行添加到您的store.js

 // When a user logs in or out, save that in the store firebase.auth().onAuthStateChanged((user) => { store.currentUser = user; });

由於這三行,每次當前登錄的用戶更改(登錄或註銷)時, store.currentUser也會更改。 讓我們發布一些球!

註銷選項的屏幕截圖
登錄狀態存儲在 store.js 文件中

輸入表單是一個單獨的 Vue.js 組件,它連接到我們商店中的writeBall函數,如下所示:

 <template> <form @submit.prevent="formPost"> <textarea v-model="message" /> <input type="submit" value="DUNK!" /> </form> </template> <script> import { store } from './store'; export default { data() { return { message: null, }; }, methods: { formPost() { store.writeBall(this.message); } }, } </script>

驚人的! 現在人們可以登錄並開始發布 Balls。 但是等等,我們缺少授權。 我們希望您只能自己發布 Balls,這就是Firestore 規則的用武之地。它們由定義數據庫訪問權限的 Javascript 代碼組成。 您可以通過 Firestore 控制台輸入它們,但也可以使用 Firebase CLI 從磁盤上的文件安裝它們。 像這樣安裝並運行它:

 npm install -g firebase-tools firebase login firebase init firestore

您將獲得一個名為firestore.rules的文件,您可以在其中為您的應用添加授權。 我們希望每個用戶都能夠插入自己的球,但不能插入或編輯其他人的球。 下面的例子做得很好。 它允許每個人閱讀數據庫中的所有文檔,但只有登錄後才能插入,並且插入的資源有一個與當前登錄用戶相同的字段“作者”。

 service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read: if true; allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.author; } } }

它看起來只是幾行代碼,但它非常強大,並且可以很快變得複雜。 Firebase 正在圍繞這部分開發更好的工具,但就目前而言,它是反複試驗,直到它以您想要的方式運行。

如果您運行firebase deploy ,Firestore 規則將在幾秒鐘內部署並保護您的生產數據。

添加服務器邏輯

在您的主頁上,您想查看您朋友的 Balls 的時間線。 根據您希望如何確定用戶看到哪些球,直接在數據庫上執行此查詢可能會成為性能瓶頸。 另一種方法是創建一個Firebase 雲函數,在每個發布的 Ball 上激活,並將其附加到作者所有朋友的牆上。 這樣它是異步的、非阻塞的並且最終是一致的。 或者換句話說,它會到達那裡。

為了使示例簡單,我將做一個小演示來聆聽創建的 Balls 並修改它們的消息。 不是因為這特別有用,而是向您展示讓雲功能啟動和運行是多麼容易。

 const functions = require('firebase-functions'); exports.createBall = functions.firestore .document('balls/{ballId}') .onCreate(event => { var createdMessage = event.data.get('message'); return event.data.ref.set({ message: createdMessage + ', yo!' }, {merge: true}); });

哦,等等,我忘了告訴你在哪裡寫這段代碼。

 firebase init functions

這將創建帶有index.js的函數目錄。 這是您可以編寫自己的Cloud Functions的文件。如果您對它印象深刻,也可以復制粘貼我的文件。

Cloud Functions為您提供了一個解耦應用程序不同部分並讓它們異步通信的好地方。 或者,在建築繪畫風格中:

Cloud Functions服務端邏輯架構圖
應用程序不同組件之間的異步通信

最後一步:部署

Firebase 為此提供了託管選項,您可以通過 Firebase CLI 使用它。

 firebase init hosting

選擇dist作為公共目錄,然後選擇“是”將所有 URL 重寫為index.html 。 最後一個選項允許您使用 vue-router 在您的應用程序中管理漂亮的 URL。

現在有一個小障礙: dist文件夾不包含指向正確構建代碼的index.html文件。 要解決此問題,請將 npm 腳本添加到您的package.json

 { "scripts": { "deploy": "npm run build && mkdir dist/dist && mv dist/*.* dist/dist/ && cp index.html dist/ && firebase deploy" } }

現在只需運行npm deploy ,Firebase CLI 就會顯示託管代碼的 URL!

何時使用此架構

此設置非常適合 MVP。 到第三次完成此操作時,您將在幾分鐘內擁有一個正常工作的 Web 應用程序 - 由免費託管的可擴展數據庫提供支持。 您可以立即開始構建功能。

此外,還有很大的成長空間。 如果Cloud Functions不夠強大,您可以回退到在 Google Cloud 中的 docker 上運行的傳統 API。 此外,您可以使用vue-routervuex升級您的 Vue.js 架構,並使用 vue-cli 模板中包含的 webpack 的強大功能。

不過,也不全是彩虹和獨角獸。 最臭名昭著的警告是您的客戶會立即與您的數據庫對話。 沒有可用於將原始數據轉換為對客戶端更容易的格式的中間件層。 因此,您必須以對客戶友好的方式存儲它。 每當您的客戶請求更改時,您都會發現在 Firebase 上運行數據遷移非常困難。 為此,您需要編寫一個自定義 Firestore 客戶端來讀取每條記錄、對其進行轉換並將其寫回。

花時間決定你的數據模型。 如果您以後需要更改數據模型,數據遷移是您唯一的選擇。

那麼使用這些工具的項目有哪些例子呢? 使用 Vue.js 的大牌包括 Laravel、GitLab 和(對於荷蘭語)nu.nl。 Firestore 仍處於測試階段,因此還沒有很多活躍用戶,但 Firebase 套件已經被National Public RadioShazam和其他人使用。 我見過同事為基於 Unity 的遊戲 Road Warriors 實施 Firebase,該遊戲在前五天的下載量超過一百萬次。 它可能需要相當多的負載,並且對於 Web、本機移動、Unity 等客戶端非常通用。

我在哪裡註冊?!

如果您想了解更多信息,請考慮以下資源:

  • 包含上述所有代碼的工作示例
  • 關於 Vue.js、vue-router、vue-cli 的文檔
  • Firebase 上的文檔
  • 一種更好地了解 Firebase 的有趣方式 — 他們的 YouTube 博客

快樂編碼!