2
votes

I know this is very simple question, but I can't find out a simple answer anywhere.

I start messing around with Firebase, and I want to just get all information of user then paste it where I need in my app.

For example, I have Database, inside I have "Users" - then keys (like -KjVkK3QCAXxMCfdyROe) and then all the info (name, age, job...).

What I come out until now is:

let app = Firebase.initializeApp(config)
let db = app.database()
let usersRef = db.ref('Users')

Then in my vue app component -

firebase: {
  users: usersRef.child('-KjVxBYyKv3_PFLavId3')
},

Now I want to know how to get the name, age, job values? I tried this.users.name - but it is undefined.

I looked and found that code, but it too long and not efficient:

this.users.on("value", function(snapshot) {
  var username = snapshot.val().name;
});

Please give hand and help me understand how can I get to the object and get the info simple like regular object. How can I turn Firebase Reference into simple Object?

2
Can you print and check what is this.usersDeepak

2 Answers

5
votes

Sanity check first: the firebase{} construct isn't automatically part of vuejs. Do you have vuefire installed?

Vuefire supports two different ways of passing data to components:

let app = Firebase.initializeApp(config)
let db = app.database()

Vue.component('myComponent', {
  firebase: function() {return {
    foo: db.ref('path/to/foo')
  }},
  mounted: function() {return {
    this.$bindAsArray('bar',db.ref('path/to/bar')); // or use $bindAsObject depending on the type of data you're loading
  }}
}

That's all that's necessary; you can now use this.foo and this.bar in component code, or {{foo}} and {{bar}} in the component template, to access the firebase data from those paths.

You don't need to do this sort of thing in your components:

this.users.on("value", function(snapshot) {
  var username = snapshot.val().name;
});

because vuefire takes care of those bindings for you.

Once you have hold of a firebase reference, you can optionally pass it to child components as a regular prop and the binding will continue to work in the child component. So for example if that parent component's template contained <child-component :foo="foo" :bar="bar"></child-component> then the child would read the data like so:

Vue.component('childComponent', {
  props: ['foo','bar'],
  // ...
}

Passing database references around as component props is optional, but in many circumstances can be simpler than having each child component request its own data reference from Firebase. (There's not much difference in terms of performance; Firebase apparently handles its own cacheing internally for duplicate requests from different components.)

TL;DR

Looking at the screenshot you posted in comments: if that's what you're getting in this.users, it looks like your data binding is working, but may be pointing to the wrong path in your database, or your database structure may not be what you expect: you've got an array of three objects instead of a single user object.

2
votes

Its better you start using vuex as your state management.

Since fetching data from firebase is asynchronous you must do the fetching process in the vuex action.

In vuex actions you can commit mutations, these are synchronous changes

So for your usage the vuex store would be:

import Vue from 'vue'
import Vuex from 'vuex'
import * as firebase from 'firebase'

Vue.use(Vuex);

export const store = new Vuex.Store({
    state:{
        user:{
            userName:'',
            orherData: null,
            someOtherData: null
        }
    },
    getters:{
        //getters return the state and can be used in your components to get the current value of the state,

        getUserInfo: (state) => {
            return state.user;
        }
    },
    mutations:{
        //mutation gets state as the 1st parameter and the paylozd you passed in the action you commited thiz mutation as 2nd parameter

        addUserInfo:(state, userInfo) => {

            //here you can change or mutate the values present in the state , in your case user.

            state.user.userName = userInfo.name;

        }
    },
    actions:{
        fetchUserData:({commit}) => {
            const ref = firebase.database().ref('Users');
            ref.child('-KjVxBYyKv3_PFLavId3').on('value', (snap) => {
                //you commit the  mutation passing the snapshot value you recieved from firebase as payload to the mutation
                commit('addUserInfo', snap.val());
            });
        }
    }

}); 

The advantage of a centalized state is that using vuex is that now you can acess your user info in any component by using getters as follows:

computed:{
    userInfo: this.$store.getters.getUserInfo;
}

The computed property userInfo can be used in the html of you component