Read data from firebase in vuex

China☆狼群 提交于 2020-04-30 06:33:46

问题


i am new in Vue Js. I am doing an TODO web application. I took firebase as a backend and database. I am using Vuex for the state management. Until now i am able to add data to firebase, but when come time to read, i am stuck. i couldn't read data from firebase. It's show an empty array in component from where i am calling.

This is my store.js

import Vue from 'vue';
import Vuex from 'vuex';
import firebase from "firebase";


Vue.use(Vuex);

export const store = new Vuex.Store({

    state:{
        events:[],
        error:''
    },

    mutations:{
        setEvent(state){
            let items = [];

            firebase.database().ref('eventos')
                .on('value',event =>{
                    event.forEach(data =>{
                        items.push(data.val())
                    })
                });

            state.events = items
        },

        setError(state, payload) {
            state.error = payload;
        },

    },

    actions:{
        addEvent(context,payload){

            firebase.database().ref('eventos/').push(payload)
                .then((event)=>{
                    context.commit('setEvent',event)
                }).catch(err =>{
                console.log(err)
            })
        },
    },

    getters:{
        eventList: state => {
            return state.events
        }
    }



});

In this component i am calling the array events to show all value

<template>
    <div>
        {{eventList}}
    </div>
</template>

<script>
    export default {
        name: "ReadEvents",

        computed:{
            eventList(){
                return this.$store.getters.eventList;
            }
        }
    }

回答1:


Data is loaded from Firebase asynchronously. While this is going on, your main code continues to run, so that the UI isn't blocked. Then once the data is available, your callback is invoked with that data.

It's easiest to see this by placing some log statements:

setEvent(state){
    console.log("Before starting to load data");
    firebase.database().ref('eventos')
    .on('value',event =>{
      console.log("Got data");
    });

    console.log("After starting to load data");
},

When you run this code, it logs:

Before starting to load data

After starting to load data

Got data

While this probably wasn't what you expected, it completely explains why your data isn't showing up. By the time you call setState, the items hasn't been populated yet.

To solve this problem, move your setState call into the on() callback:

setEvent(state){
    firebase.database().ref('eventos')
    .on('value',event =>{
        let items = [];
        event.forEach(data =>{
            items.push(data.val())
        })
        state.events = items
    });
},

Unrelated to the current problem, I highly recommend also storing data.key in your array, as you're bound to need it down the line when you need to find an item from the array in the database.

The code for that could be for example:

event.forEach(data =>{
    items.push({ "$id": data.key, ...data.val() })
})

So with this, the key is stored in $id, while all the other properties are copied as is.




回答2:


For a start, you shouldn't try to execute any asynchronous code in vuex mutations, see https://vuex.vuejs.org/guide/mutations.html#mutations-must-be-synchronous

Instead, include the logic in your action, and only call the mutation when you have the data that you want to commit to the state. Something like this:

export const store = new Vuex.Store({
    state: {
        events: [],
        error: ''
    },

    mutations: {
        setEvents (state, events) {
            state.events = events;
        },

        setError (state, payload) {
            state.error = payload;
        }
    },

    actions: {
        addEvent ({ commit }, event) {
            firebase.database().ref('eventos').push(event)
            .then(() => {
                firebase.database().ref('eventos')
                .on('value', data => {
                    const events = data.map(item => { 
                        return { "$id": item.id, ...item.val() };
                    });
                    commit('setEvents', events);
                });
            })
            .catch(err => {
                console.log(err);
            })
        },
    },

    getters:{
        eventList: state => {
            return state.events;
        }
    }
});


来源:https://stackoverflow.com/questions/61001363/read-data-from-firebase-in-vuex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!