Vuefire: It is difficult for me to understand how to use all firebase features

Created on 27 Jul 2016  路  31Comments  路  Source: vuejs/vuefire

Hi, my friends,

I have learned the feature of "vuefire" and tried an example successfully. In a component to get the data from firebase like this:

const componentsRef = new Firebase('https://project-d40ad98.firebaseio.com/components')
export default {
    name: 'NewSectionDialog',
    firebase: {
      comps: componentsRef
    },
}

But I have some questions on this.

  1. In a big project, did i need new one Firebases in each component which needs to get itself data? If yes, it would be have many firebase in one project.
  2. I learned how to control one data depend on vuefire and firebase, but how could i using the storage to control the files. If like this:
const storageRef = new Firebase('https://project-d40ad98.firebaseio.com').storage().ref()
const uploadRef = storageRef.child('upload')
export default {
    name: 'UploadImage',
    firebase: {
        upload: uploadRef
    },
}

All of this questions because i am quite difficult to understand the firebase and how to use. Could you help me? Help me with giving some examples and i am very smart to get the knowledge.

Thank you for your time and kindness.

Most helpful comment

I dont want to initialize a new firebase instance for each component, that was my initial problem.

You don't have to.

I dont believe that Vue, a very sophisticated framework dont allow us to use DRY.

Of course it does. Or rather - JS modules allow you that.

Simply initialize the Firbase instance in its own module once, and export it from there. Then you can import this instance in every component as needed:

//.db.js
import Firebase from 'firebase'
const firebaseApp = Firebase.initializeApp({ /*FIREBASE_CONFIG*/})
const db = firebaseApp.database()
export default db

// in your component:
import './db'

export default {
  firebase {
    example: db.ref('example')
  }
}

All 31 comments

I haven't practiced yet, so I'm not sure if it will work. You can pass db or ref as props from parent component and use it in firebase property as this.db.ref() or this.someRef

export default {
  props: ['db']
  firebase: {
    anArray: this.db.ref('/path/to/ref')
  }
}

it should be a callback, but Mr. Evan You don't mention it in README, so I don't know if it even exist

export default {
  props: ['db']
  firebase: function () {
  return {
    anArray: this.db.ref('/path/to/ref')
    }
  }
}

You should give Firebase documentation a look, it's great 馃槈
Start over here: https://firebase.google.com/docs/web/setup

@voanhcuoc firebase should be an object, not a function. I'm curious about why do you think it should be a function. Where did you get that information?

@posva I'm confusing whether this.db is available at firebase creation time, does Vuefire ensure that ?

@voanhcuoc Where did you get that example from?
The only thing you pass to vuefire are refs

@posva yeah, I just guessed :smile: , after all my approach about this issue is right, we pass the refs or the whole db as props over and over to smaller components, so that each component can make use of the ref it need, isn't it ?

Well, I'll rather pass the ref key as a prop a have a shared db instance across components. That looks simpler imo

Closing this as the OP hasn't updated in a while

@posva I too have problems getting started with vuefire. For example, with the webpack boilerplate, let's suppose that I import VueFire and Firebase in the main.js file, how do I use the data in a component? For example in the Hello.vue component? I think the documentation is lacking these basic examples. Thanks!

A webpack example with usage in the main app and the components would be nice. See https://github.com/vuejs/vuefire/issues/30

Yeah, I'm having the same difficulty to understand how to access global firebase from a child component. I tried to put the following code in the component script:

import * as firebase from 'firebase'

var db = firebase.database()

but got this error:

Uncaught Error: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp().

I assume you are calling firebase.initializeApp() in your parent component, right? In general, when your app bootstraps, you should call firebase.initializeApp(). Then, in your child components, make sure your var db = firebase.database() call is executed _once the component is created_ not when the file is imported. Otherwise, it will execute before firebase.initializeApp() is called and you'll get that error. So, if you move that line into your child component's init code, it should work.

@jwngr thank you, I moved the var db = firebase.database() to beforeCreate hook, but now when I try to do this:

firebase: {
    example: db.ref('example')
},

the db variable doesn't exist in that context, what am I missing? how should I access db var inside firebase property?

I have no idea where you are putting that code snippet, but you probably just need to do var db at the top of the file and then db = firebase.database() in your beforeCreate hook. Then db should be visible to the entire file scope.

here is my Example.vue component code:

<template>
    ...
</template>

<script>
    import * as firebase from 'firebase'

    export default {
        beforeCreate() {
            var db = firebase.database()
        },
        firebase: {
            example: db.ref('example')
        }
    }
</script>

error: Uncaught ReferenceError: db is not defined

The db variable should be after the import, the console is telling you that the db variable doesn't exist outside of beforeCreate scope.

Edit: try this, basically you always have to initialize the app again...unless you use vuex which is not trivial to understand ;p

<script>
    import Firebase from 'firebase'
    const firebaseApp = Firebase.initializeApp({ /*FIREBASE_CONFIG*/})
    const db = firebaseApp.database()
    export default {
        firebase: {
            example: db.ref('example')
        }
    }
</script>

@microcipcip, I dont want to initialize a new firebase instance for each component, that was my initial problem. I dont believe that Vue, a very sophisticated framework dont allow us to use DRY. I'm using Vue CLI and have initialized firebase in main.js.

I liked @jwngr suggestion, but now I just need to know how to create a variable inside beforeCreate lifecycle hook and access it inside firebase property of my component

I dont want to initialize a new firebase instance for each component, that was my initial problem.

You don't have to.

I dont believe that Vue, a very sophisticated framework dont allow us to use DRY.

Of course it does. Or rather - JS modules allow you that.

Simply initialize the Firbase instance in its own module once, and export it from there. Then you can import this instance in every component as needed:

//.db.js
import Firebase from 'firebase'
const firebaseApp = Firebase.initializeApp({ /*FIREBASE_CONFIG*/})
const db = firebaseApp.database()
export default db

// in your component:
import './db'

export default {
  firebase {
    example: db.ref('example')
  }
}

Nice solution @LinusBorg, thank you very much!

@LinusBorg, in your last example (this is more a question about how ES6 works) are you actually initializing Firebase for every db import in each component, or is webpack/babel clever enough to initialize it only once?

modules are only "executed" once - wherever in the programm they are imported first. subsequent imports will simply receive a reference to the result of the first one.

Ok, thanks :)

Hi,

It looks like @LinusBorg solution does not work anymore.
I now have this error:

[Vue warn]: Property or method "example" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

"example" is the variable name set in component like in @LinusBorg comment:

export default {
  firebase {
    example: db.ref('example')
  }
}

Any ideas?

@f-k-z I'd like to know the solution to this as well. Thanks.

Okay, here is what I ended up doing...

I created a ../firebase.js file with the following code. Place the file where it makes sense for your project.

// So, inside ../firebase.js
// Initialize Firebase
  import Firebase from 'firebase'

  let config = {
    apiKey: "...",
    authDomain: "...",
    databaseURL: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "..."
  };
  let firebaseApp = Firebase.initializeApp(config)
  let db = firebaseApp.database()

  export default db

Then I created a component file ./components/Search.vue

Inside the script tags I implemented the following:

  <script>

    // import the firebase file using a variable name. I chose db in this case
    import db from '../firebase.js'

    // then I used the db variable like this
    let membersRef = db.ref('members')

    export default {
      name: 'search',
      firebase: {
        members: membersRef
      }
    }

  </script>

Then within the same ./components/Search.vue file, I was able to implement code like the following:

<template> ... <!-- DATA ROW --> <div style="display: flex;" v-for="member in members"> <div style="flex: 1 0 0;padding:10px;">{{member.firstname}}</div> <div style="flex: 1 0 0;padding:10px;">{{member.lastname}}</div> <div style="flex: 1 0 0;padding:10px;">{{member.city}}</div> <div style="flex: 1 0 0;padding:10px;">{{member.state}}</div> <div style="flex: 1 0 0;padding:10px;">{{member.zip}}</div> </div> ... </template>

You can ignore my styles. Style it however you like. The v-for directive and the member.fieldname notation are the important parts, along with the portion within the script tags.

Basically, the export in the firebase.js file and the import in the Search.vue file allow you to use one firebase instance across multiple components.

Hope that helps someone :-)

Hi Charles,
Thanks, actually I opened another ticket about this and found out that my error was about something else and not about firebase.

Anyway, I eventually use the @LinusBorg solution (just like yours) and it works well.

By the way, thanks for sharing you explanation, I think it will certainly help :)

I just used this because I was running into the issue while using vue-router. I couldn't figure out how to pass the database object to the child component I needed. Thanks so much @CharlesMcKeever and @LinusBorg

@CharlesMcKeever I followed your steps but I still get a can't find variable db error in the console.

this.helpedMe()

Thanks, I did it the @CharlesMcKeever way.
Here is another article that helped me.
https://alligator.io/vuejs/vuefire-firebase/

@CharlesMcKeever Thanks for your solution, it almost works but I get this error in the console : "Uncaught TypeError: Cannot read property 'ref' of undefined"

This is my db import inside a Vue module :
import {db} from '../main.js'
let recipesRef = db.ref('recipes')

Any idea why it can't read 'ref'?

@Fabrunet It seems like you're not exporting "db" correctly in your main.js. I would suggest putting your full code on online IDE like https://codesandbox.io/s/vue, and ask the question on forum like StackOverflow.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

franciscolourenco picture franciscolourenco  路  7Comments

patrikengborg picture patrikengborg  路  4Comments

magicseth picture magicseth  路  6Comments

rstormsf picture rstormsf  路  4Comments

dev-kr2020 picture dev-kr2020  路  4Comments