Search code examples
firebasewebpackfirebase-realtime-databasevue.jsweb-component

(Webpack failing to build?) Firebase DB in different levels of Vue components


I'm trying to set up a vue-fire app using single file Vue components.
I'm using the standard (full) Vue-cli Webpack template available on the official site.

I have firebase loaded in App.vue like this:

 let config = {
     ...
 };
 let app = Firebase.initializeApp(config);
 let db = app.database();
 let usersRef = db.ref('users');

...

export default {
     name: 'app',
     data () {
         return {
             login: {
                 email: '',
                 password: ''
             },
             newUser: {
                 email: '',
                 password: ''
             },
             showRegister: false
         }
     },
     firebase: {
               users: usersRef,
     },
     ...
}

I'm using Vue-router and my routes are set up like this:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import News from '@/components/News'

Vue.use(Router)

export default new Router({
  routes: [
      {
          path: '/',
          name: 'Home',
          component: Home
      },
      {
          path: '/news',
          name: 'News',
          component: News

      }
  ]
})

I would like to be able to access my Firebase app in the 'News' component. The problem is that if I include the entire Firbase setup in the News.vue file, I get the error:

[DEFAULT]: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).

The recommended solution is to export the initialized app's database in App.vue and import it in the child component. So I add this to the bottom of my App.vue script:

 module.exports.FBApp = app.database();

And this to News.vue:

 import FBApp from '../App.vue'
 let usersRef = FBApp.ref('users')

But now I am getting the following error:

TypeError: __WEBPACK_IMPORTED_MODULE_0__App_vue___default.a.ref is not a function

Does anyone know how to do this? Surely it can't be too hard.


Solution

  • Create a db.js file like the following alongside app.vue.

    import firebase from 'firebase'
    
    var config = {
      apiKey: 'xxxxx'
      authDomain: 'xxxxx'
      databaseURL: 'xxxxx'
      projectId: 'xxxxx'
      storageBucket: 'xxxxx'
      messagingSenderId: 'xxxxx'
    }
    const firebaseApp = firebase.initializeApp(config)
    
    const db = firebaseApp.database()
    
    export default db
    

    In your main.js:

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import VueFire from 'vuefire'
    
    // explicit installation required in module environments
    Vue.use(VueFire)
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: { App }
    })
    

    And now in any component, eg:

    <template>
      <span>
        {{ news }}
      </span>  
    </template>
    <script>
    import db from '../db'
    export default {
      data: function () {
        return {
          users: [],
          sample: []
        }
      },
      firebase: function () {
        return {
          news: db.ref('news')
        }
      }
    }
    </script>