【问题标题】:How to tell a Vue app to use Firebase emulator?如何告诉 Vue 应用使用 Firebase 模拟器?
【发布时间】:2020-06-17 14:03:03
【问题描述】:

我有一个利用 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

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')

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

【问题讨论】:

    标签: javascript firebase vue.js vue-cli


    【解决方案1】:

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


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

    第一步,您需要编辑 package.json 以设置 Vue 执行监视/构建周期而不是热重载周期,如下所示。唯一不起作用的(AFAIK)是 Vue DevTools 扩展。 (快速注意,我使用的run-srun-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"
    }
    

    安装所需的开发依赖项

      npm i --save-dev firebase-tools npm-run-all
    

    所以,这很多。让我分解一下每个命令在做什么:

    • 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 Documentation,这个问题实际上有一个非常简单的解决方案。您需要做的是从 Firebase 保留 URL 请求一个特殊文件。在我的示例中,我使用 Axios,但无论如何,您可以随意使用任何库来发出您想要的请求。

    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;
    

    另外,要向 Vue 实例添加属性,最好这样做,以避免垃圾收集或命名冲突的任何问题。然后,在任何 Vue 组件中,您都可以使用 this.$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');
    

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


    奖励:部署

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

    "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",
      "deploy": "run-s build deploy:firebase",
      "deploy:firebase": "firebase deploy",
      "lint": "vue-cli-service lint",
      "serve": "run-s build:dev watch",
      "serve:firebase": "firebase serve",
      "watch": "run-p build:watch serve:firebase"
    }
    

    【讨论】:

    • 感谢您提供所有详细信息。但我仍然无法弄清楚这一点。您如何使用步骤 1 中的脚本? Axios 脚本在哪里,你如何调用它?如果您可以添加一些有关如何将所有这些部分一起使用的详细信息,我们将不胜感激!
    • 很好的回答,帮了大忙!!!也可以运行 Firebase Emulators(完整),我为我创建了一些额外的命令:“firebase:emulators:start”:“firebase emulators:start”,“watch:fb-emu”:“run-p build:watch firebase:模拟器:开始”
    【解决方案2】:

    更新于 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;
    

    这可以导入到 Vuex 商店,或任何其他类似的页面:

    import { Firestore, FirebaseFunctions } from '@/services/firebase.js';
    

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

    firebase emulators:start
    

    这也适用于 Nuxt。

    【讨论】:

    • 这种方法对我有用。我只运行函数和firestore模拟器,然后在另一个窗口中使用“npm run serve”,它连接到模拟器。通过这种方式,我可以轻松地迭代 Vue 代码,但让它与本地模拟器对话。有没有办法使用托管模拟器并在我更改 vue 代码时更新它?
    • @Adam 可能有一种方法,但我对 Webpack 的了解不足以告诉你如何做。
    • 文档现在说的不同了,说明已经改变了
    • @tonjo 感谢提醒:我已经更新了我的答案。
    【解决方案3】:

    在 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 };
    

    就是这样 :-) 我花了 10 多个小时才弄明白。

    【讨论】:

      猜你喜欢
      • 2021-02-13
      • 1970-01-01
      • 2021-04-25
      • 2021-09-16
      • 2021-09-30
      • 2020-02-29
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多