Search code examples
firebasevue.jsgoogle-cloud-firestorevuex

How to get collection from firestore and set to vuex state when the app is rendered?


I have a firestore collection called categories. The documents in this collection are used by every page (route) in my vue application so I figured that the most efficient way to access this data would be to have a categories state in my store.js such that each component can access the categories state when it needs to instead of getting it from firestore each time. How would I set the contents of the categories collection to my vuex state when the application is rendered?

Here is my store.js:

import Vue from 'vue'
import Vuex from 'vuex'
const fb = require('./components/firebase/FirebaseConfig.js')

Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {
        categories: []
    },
    actions: {
        fetchCategories({commit, state}) {
            fb.categoriesCollection.get().then((querySnapshot) => {
                if (querySnapshot.empty) {
                    //this.$router.push('/HelloWorld')

                } else {
                    this.loading = false
                    var categories = []
                    querySnapshot.forEach((doc) => {
                        categories.push(doc.data());
                    })

                    this.categories = categories
                }
         })
    },  
    mutations: {
        setCategories(state, val) {
            state.categories = val
        }
    }
})

I know I can call fetchCategories using:

this.$store.dispatch('fetchCategories')

but I am unsure where to put this.


Solution

  • The data can be fetched with an action inside the store. within the action commit the changes to update the state.

    Once your store is created, you can immediately dispatch the fetch action by calling store.dispatch:

    store.js

    import Vue from "vue";
    import Vuex from "vuex";
    const fb = require("./components/firebase/FirebaseConfig.js");
    
    Vue.use(Vuex);
    
    const store = new Vuex.Store({
      state: {
        categories: []
      },
      actions: {
        fetchCategories({ commit }) {
          fb.categoriesCollection.get().then(querySnapshot => {
            if (querySnapshot.empty) {
              //this.$router.push('/HelloWorld')
            } else {
              this.loading = false;
              var categories = [];
              querySnapshot.forEach(doc => {
                categories.push(doc.data());
              });
    
              commit("setCategories", categories);
            }
          });
        }
      },
      mutations: {
        setCategories(state, val) {
          state.categories = val;
        }
      }
    });
    
    store.dispatch("fetchCategories");
    
    export default store;
    

    The store should be exported apart from the declaration