如何告诉 Vue 应用程序使用 Firebase 模拟器?

sta*_*af1 7 javascript firebase vue.js vue-cli

我有一个利用 Firebase Cloud Functions 的 Vue 应用程序,我已将其配置如下。

src/plugins/firebase.js

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

const firebaseConfig = {
  apiKey: 'my-api-key',
  authDomain: 'my-project.firebaseapp.com',
  databaseURL: 'https://my-project.firebaseio.com',
  projectId: 'my-project',
  storageBucket: 'my-project.appspot.com',
  messagingSenderId: '12345678910',
  appId: '123456789101112',
  measurementId: 'ASDFJKL'
}

firebase.initializeApp(firebaseConfig)

export default firebase
Run Code Online (Sandbox Code Playgroud)

src/main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// Other imports goes here
import firebase from './plugins/firebase'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  // Other includes goes here...
  firebase,
  render: h => h(App)
}).$mount('#app')
Run Code Online (Sandbox Code Playgroud)

我想使用 Firebase 模拟器来测试一下,但我不知道要改变什么来实现这一点。

小智 13

好的,所以这将是一个很长的答案,但我希望尽可能完整地回答您的问题。该过程实际上分为两个阶段:使模拟器(包括热重载)与 Vue 一起工作,然后使 Vue 与 Firebase 的模拟版本一起工作。


第 1 步:使 Firebase 模拟器与 Vue 配合使用

第一步,您需要编辑您package.json的设置 Vue 以执行监视/构建周期而不是热重载周期,如下所示。唯一不起作用(AFAIK)的是 Vue DevTools 扩展。(快速说明,我使用的run-sandrun-p命令来自npm-run-all包,因为我在 Windows 上并且cmd.exe不喜欢单个&符号&)。此外,要使用firebase脚本中的命令,您需要将firebase-tools软件包安装为开发依赖项。

"scripts": {
  "build": "vue-cli-service build",
  "build:dev": "vue-cli-service build --mode development",
  "build:watch": "vue-cli-service build --mode development --watch --no-clean",
  "lint": "vue-cli-service lint",
  "serve": "run-s build:dev watch",
  "serve:firebase": "firebase serve",
  "watch": "run-p build:watch serve:firebase"
}
Run Code Online (Sandbox Code Playgroud)

安装所需的开发依赖项

  npm i --save-dev firebase-tools npm-run-all
Run Code Online (Sandbox Code Playgroud)

所以,这就很多了。让我分解每个命令的作用:

  • watch:这个命令只是让一切顺利的 shell 命令。它依次运行buildserve命令。稍后会详细介绍
  • serve:此命令启动实际的监视/构建周期。它启动 Firebase 模拟器并开始vue-cli-service监视更改。
  • serve:firebase:此命令会启动 Firebase 模拟器……仅此而已。
  • build:此命令执行生产构建...此处并未真正使用,但为了完整性将其保留。
  • build:dev: 这个命令有点重要。如果您注意到,在初始watch脚本中,我们build:dev首先调用了脚本。这是因为如果您启动 Firebase 模拟器并且您的“公共”目录(注意:这是 Firebase 的公共目录,而不是 Vue 的)被删除,那么 Firebase 实际上会崩溃。因此,为了解决这个问题,我们开始构建/监视周期之前完成构建。
  • build:watch:这就是热重载魔法发生的地方。我们告诉vue-cli-service构建应用程序,但也要注意更改而不是清理构建目录。监视更改启动前面提到的监视/构建周期。我们告诉它不要清理构建目录,因为 Firebase 不关心它所服务的目录中的文件是否发生变化,但如果目录被删除,它就会崩溃。

这种方法的唯一缺点是 Vue DevTools 不起作用。


第 2 步:让 Vue 与 Firebase 模拟器一起工作

事实证明,由于Firebase 文档,这个问题实际上有一个非常简单的解决方案。您需要做的是从 Firebase 保留网址请求一个特殊文件。在我的示例中,我使用 Axios,但无论如何,您可以随意使用任何库来提出您想要的请求。

  npm i --save-dev firebase-tools npm-run-all
Run Code Online (Sandbox Code Playgroud)

此外,要向 Vue 实例添加属性,最好这样做,以避免垃圾收集或命名冲突的任何问题。然后,在任何 Vue 组件中,您都可以使用this.$firebase.

import axios from 'axios';
import firebase from '@firebase/app';
import '@firebase/auth';
import '@firebase/firestore';
import '@firebase/functions';

axios.get('/__/firebase/init.json').then(async response => {
  firebase.initializeApp(await response.data);
});

export default firebase;
Run Code Online (Sandbox Code Playgroud)

理想情况下,会有一些方法来区分应用程序是否在模拟器中运行,但实际上它可以解决的唯一问题是使用 Vue DevTools 扩展的能力,我并没有真正看到(双关语)作为要求。但是,除此之外,您应该在模拟器中启动并运行,实时重新加载;而且,最重要的是,一旦准备就绪,您无需对应用程序进行任何更改即可部署它。


奖励:部署

所以,这里是另一个脚本部分,它具有与上面相同的所有内容,但还包括一个 1 命令部署,以确保您将生产构建从 Vue 部署到 Firebase。

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import firebase from './plugins/firebase';

Vue.config.productionTip = false;
Vue.prototype.$firebase = firebase;

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app');
Run Code Online (Sandbox Code Playgroud)


小智 11

2021 年 1 月 14 日更新以反映 Firebase SDK 的变化。

关于连接到 Firestore 模拟器的官方文档在这里:https : //firebase.google.com/docs/emulator-suite/connect_firestore

有关连接到 Functions 模拟器的官方文档在这里:https : //firebase.google.com/docs/emulator-suite/connect_functions

在实践中,设置将如下所示:

import * as Firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/functions';
import 'firebase/storage';

const firebaseConfig = { <Per Firebase Console> };

!Firebase.apps.length ? Firebase.initializeApp(firebaseConfig) : '';

if(window.location.hostname === 'localhost') {
  Firestore.firestore().useEmulator('localhost', 8080);
  Firestore.functions().useEmulator('localhost', 5001);
  /* OLD implementation */
  // Firebase.firestore().settings({ host: 'localhost:8080', ssl: false });
  // Firebase.functions().useFunctionsEmulator('http://localhost:5001');
}

export const GoogleAuthProvider = new Firebase.auth.GoogleAuthProvider();
export const FirebaseAuth = Firebase.auth();
export const Firestore = Firebase.firestore();
export const FirebaseFunctions = Firebase.functions();
export const FirebaseStorage = Firebase.storage();
export default Firebase;
Run Code Online (Sandbox Code Playgroud)

这可以导入到 Vuex 商店或任何其他页面,如下所示:

import { Firestore, FirebaseFunctions } from '@/services/firebase.js';
Run Code Online (Sandbox Code Playgroud)

然后在命令提示符/终端中运行:

firebase emulators:start
Run Code Online (Sandbox Code Playgroud)

这也适用于 Nuxt。


chr*_*er1 7

于 2021 年 11 月使用 Firebase Web 版本 9 进行更新:使用与 starleaf1 相同的配置设置,将 firebase.js 更改为以下内容:

import { initializeApp } from "firebase/app";
import { getAuth, connectAuthEmulator } from "firebase/auth";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";

initializeApp({
    apiKey: "xxx",
    authDomain: "xxx",
    projectId: "xxx",
    storageBucket: "xxx",
    messagingSenderId: "xxx",
    appId: "xxx"
});

const db = getFirestore();
const auth = getAuth();

// If on localhost, use all firebase services locally
if (location.hostname === 'localhost') {
    connectFirestoreEmulator(db, 'localhost', 8080);
    connectAuthEmulator(auth, "http://localhost:9099");
    // add more services as described in the docs: https://firebase.google.com/docs/emulator-suite/connect_firestore
}

export { db, auth };
Run Code Online (Sandbox Code Playgroud)

就是这样:-) 我花了 10 多个小时才弄清楚这一点。