使用 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 博客

快乐编码!