[译]Vue.js 结合 Firestore 实际应用

Vue.js 结合 Firestore 实际应用

作者: Lukas van Driel | 译:永无止晋
原文地址:https://www.smashingmagazine.com/2018/04/vuejs-firebase-firestore/

你想做一个网站或者APP,竟然没有服务器?竟然没有数据库?竟然没有域名?你还不会后端技术?那都不是事儿!本文讲解如何利用 Firestore 配合 vue.js 做一个“八卦”网站。
ps: 访问 firebase 控制台需要“蓝灯”等网络代理

Firestore 是 Google Firebase 的一种新的数据存储方式(目前处于测试阶段),它以 Firebase 实时数据库为基础,且增加了一些漂亮的功能。在本文中,我们将使用 Vue.js 和 Firestore 建立一个网站。

假设你想制作一个新的产品(例如下一个 Twitter ,Facebook 或 Instagram )。 首先,你要制作本产品的原型或最小可行产品,即 MVP(Minimum Viable Product), 这样尽可能快地构建应用程序的核心,以便你可以将其展示给用户获取反馈并分析使用情况。这样用最短的时间完成,后续也可以快速迭代。

开始之前,我们先来给这个产品起一个厉害的名字,我们就叫它 “Amazeballs” 。

下面是我预想的设计:

Amazeballs 的定位是—–一个与朋友们分享生活中的“八卦”的应用。网站分为两部分,上面区域,我们放一个输入表单用来发表你的“八卦”,下面用来展示好友们的“八卦”。

构建一个 MVP,你需要能够快速实现功能,随后可以灵活的添加和更改功能的工具。Amazeballs 的技术选型为 Vue.js( JavaScript 渲染框架),并用 Firebase(by Google)以及他的实时数据库—- Firestore 提供支持。

Firestore 可以使用传统的HTTP请求直接访问,可以让你在没有任何服务器的情况下在线存储数据,这使得它成为一个完整的后端即服务解决方案。

以上听起来可能有点挑战性,但其实很容易,我会引导你一步一步的创建和托管这个网站。不要看这篇文章有一个长长的滚动条,它并没有很多步骤。当然,如果你想直接看这个项目的源码,你可以在  GitHub 上下载并运行程序。

让我们开始吧

我们从 Vue.js 开始,这是一个非常适合 JavaScript 初学者的框架,别小看了它,它包含了很多强大的功能,可以从 HTML 开始并逐渐添加逻辑,这也使它成为我前端框架的首选。

Vue.js有一个搭建项目脚手架的命令行界面(CLI)。 我们将使用它快速搭建项目开发环境。 首先,安装 CLI ,然后使用它来创建基于 webpack-simple 模板的新项目。

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

如果您按照以上截图上的步骤( npm install和npm run dev ),浏览器将打开一个大 Vue.js 徽标。

恭喜你,项目的脚手架已经搭建成功,好的开头是成功一半哦。

下一步,我们需要创建一个 Firebase 项目,打开  firebase 控制台(由于网络问题,控制台打开过程可能有点慢,请耐心等待),点击添加项目创建一个项目。一个项目从免费的 Spark 计划开始,它为您提供有限的数据库(1 GB 数据,每天读取5万次)和1 GB 托管。 这对我们的 MVP 来说已经绰绰有余。当访问量不断增大时,可以升级配置。

点击“将 Firebase 添加到您的网页应用”来查看你需要的配置信息。我们将在应用程序中使用这个配置,和 Vue.js 的状态管理配合使用使一种很好的方式。

首先运行 npm install firebase 安装 firebase ,然后创建一个文件 src/store.js 。这个文件将会被用来做状态管理,让每一个 Vue 组件都可以独立于组件树去访问它。以下是该文件的内容:

import Vue from 'vue';
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';

// 初始化 Firebase, 从云控制台辅助
var config = {
    apiKey: "AIzaSyCsXiKteCMbIhsDpGK277SR8A8P3HOjC8U",
    authDomain: "amazealls-24823.firebaseapp.com",
    databaseURL: "https://amazealls-24823.firebaseio.com",
    projectId: "amazealls-24823",
    storageBucket: "amazealls-24823.appspot.com",
    messagingSenderId: "187582214062"
};
firebase.initializeApp(config);

// 共享状态对象,即任何vue组件
// 可以访问
export const store = {
    ballsInFeed: null,
    currentUser: null,
    writeBall: (message) => console.log(message)
};

现在我们将添加 Firebase 部分的功能。用下面代码获取 Firestore 数据:

// 引用balls
const ballsCollection = firebase.firestore().collection('balls');
// onSnapshot 在数据改变时执行
// 在底层的firestore集合中进行更改
// 它将通过一个引用数组传递给
// 与你的查询匹配的文档
ballsCollection
    .orderBy('createdOn', 'desc')
    .limit(5)
    .onSnapshot((ballsRef) => {
        const balls = [];
        ballsRef.forEach((doc) => {
        const ball = doc.data();
        ball.id = doc.id;
        balls.push(ball);
    });
console.log('Received Balls feed:', balls);
store.ballsInFeed = balls;
});

然后用 firebase 的一个写入方法替换 writeBall 函数。

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

注意两者如何完全解耦。 当你插入一个集合时,执行了 add 方法, onSnapshot 也会被触发。 这使得我们的状态管理变得更容易。

现在有了一个共享的状态对象,任何Vue组件都可以很容易访问。接下来,让我们好好利用它。

接下来的工作

首先,让我们看看当前的用户是谁。

Firebase 有身份验证 api ,可以替你分担一些关于用户的工作。打开 Firebase 控制台,进入你刚刚创建的项目,然后依次点击 Authentication登录方法,来启动适当的身份验证选项。现在,我们用一个非常普通的按钮来使用 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 里。把下面代码加进你的 store.js

// 当一个用户登录或登出时,保存这个动作到store
firebase.auth().onAuthStateChanged((user) => {
    store.currentUser = user;
});

有了这三行,每当当前登录的用户更改(登录或注销)时,store.currentUser 也会更改。登录搞定了, 让我们发布一些“八卦”吧。

输入表单是一个单独的 Vue.js 组件,它连接到我们 store 中的 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);
        }
    },
}

很好,现在用户可以登录并发布“八卦”了。但是,我们还缺少授权功能,这就倒了 Firestore 的用武之地。它们由 Javascript 代码组成,定义了对数据库的访问权限。你可以通过 Firestore 控制台输入它们,也可以使用 Firebase CLI 安装它们。按照以下命令安装并运行(不要使用git 的命令行终端):

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

完成上述步骤,在你的工程里你可以看到一个 firestore.rules 文件,你可以在这里添加你应用的授权。我们希望每个用户只能添加自己的“八卦”,而不是添加或编辑别人的“八卦”。下面有一个不错的例子,它允许每个人读取数据库中的所有文档,但只有在登录后才能添加,并且插入的数据有一个字段 “author” ,就是当前登录的用户名。

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 规则将在数秒内部署并保护你的生产数据。

添加服务逻辑

在你的主页上,你想看到你的朋友们的“八卦”的时间线,取决于你想让用户看到哪些八卦,直接在数据库上执行这个查询可能会成为性能障碍。有一种解决方案是,是创建一个 Firebase 云端服务,在每个发布的“八卦”上激活并给所有作者的朋友查看的权限。这样它就是异步的,非阻塞的,并且最终一致的。

以上说的过于抽象,下面我来演示一个小小的例子,监听“八卦”的创建并修改他们的消息。 下面让我们看一下如何让云功能正常运行。

运行以下命令:

firebase init functions

初始化完成后,工程中会创建一个 functions 文件夹,你可以在 index.js 中编写自己的云端功能的文件,如果您对它印象深刻,不要直接复制粘贴我的云功能函数。

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 有自己的托管选项来实现部署,用命令行工具执行以下命令:

firebase init hosting

选择 dist 文件夹作为一个公共目录,然后选择 “Yes” 把所以 URL 指向 index.html。最后一个选项可以允许你使用 vue-router 来管理你应用的页面跳转。

进行到这一步,还有一个小障碍:dist 文件夹里面没有包含 index.html 文件,我们在 package.json 中添加以下 npm 脚本

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

现在只需运行 npm deploy ,用成功运行后给出的URL在浏览器访问即可!

何时使用这个架构

Firebase 非常适合做 **MVP** 。等你用这个架构做过两到三个项目时,你可以在几分钟内拥有一个免费托管的,可扩展数据库支持的应用,并且可以快速开始实现一些功能。

此外,这套架构还有很大的发展空间,如果现有云功能满足不了你的需求,你还可以使用 Google Cloud 的一些常用的API来替代它。此外,你可以使用 vue-router 和 vuex 升级你的 Vue.js 体系结构,并可以配合 webpack 和 vue-cli 实现更强大的功能。

但它也不是十全十美的,最大的一个问题是,用户可以直接操作你的数据库,没有中间层可以用来将原始数据转换成更容易为客户端所用的格式。所以,你必须以更友好的的方式存储它。还有,每当客户更改需求的时候,你会发现在 Firebase 上进行数据迁移很困难。为此,你需要编写一个定制的 Firestore 客户端来读取每条记录,进行转换并写回。

是不是想问现在有哪些应用实例? Laravel ,GitLab 和 nu.nl  这些“大牌”都在配合 vue.js 使用Firebase 。Firestore 仍处于测试阶段,因此目前还没有很多活跃的用户,但 Firebase 套件已被美国国家公共广播,Shazam 等用户使用。我身边也有同事为基于 Unity 的游戏 “ Road Warriors ” 实施了 Firebase ,并在前五天内下载了超过一百万次。它可能需要相当多的负载,并且对于 Web ,本地移动设备,Unity等客户端来说非常灵活。

如果你想学习更多,请参考以下代码

–本文的例子 ,包含本文所有代码
– Vue.js,  vue-router,  vue-cli 的文档
–Firebase 的文档
-更好地了解 Firebase 的有趣方式— their YouTube Blog

 

 

更多内容请关注我们团队的公众账号“全栈探索”。定期会有好文推送,满满的干货。

文章来源:

Author:曹 晋
link:https://jdc.jd.com/archives/212327