Lukas
Lukas

Reputation: 7734

Check logged user in firebase with Nuxt.js middleware

I've built some middleware for my Nuxt app.

import api from '~/api/Api.js'

export default function ({router, store}) {
  return api.auth().onAuthStateChanged(function (user) {
    store.state.user = user
    if (user) {

    } else {

    }
  })
}

Now, how to actually get access to the user object? When i'm doing this from normal component it's working correctly. Passing to store simple string also works, but any other action no, is there need of some kind of promise? Thx for help.

Upvotes: 0

Views: 1902

Answers (1)

richter
richter

Reputation: 451

From the Vuex documents:

The only way to actually change state in a Vuex store is by committing a mutation. Vuex mutations are very similar to events: each mutation has a string type and a handler. The handler function is where we perform actual state modifications (Documentation link)

Mutations also trigger the DOM update in Vue, so that by committing a mutation, the reactive elements are updated, whereas directly manipulating state by sending a string will not cause the reactive update. From the Vuex docs:

Since a Vuex store's state is made reactive by Vue, when we mutate the state, Vue components observing the state will update automatically

The section entitled "Mutations Follow Vue's Reactivity Rules" has a more detailed run-down on this.

The caveat here is that mutations will only work for synchronous data. If you have async data, Vuex actions will be of assistance - they can perform a mutation and handle asynchronous events.

In the absence of further example code, it is difficult to asses whether there are other issues at play here, however I have included a sample store file that works for this exact scenario. Whilst not nuxt-specific, the principle is the same:

// store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  user: {},
  files: [],
  token: ''
}

const mutations = {
  logOut (state) {
    state.user = null
  },
  setUser (state, user) {
    state.user = user
  },
  setToken (state, token) {
    state.token = token
  }
}

const actions = {
  logOut: ({ commit }) => commit('logOut'),
  setUser: ({ commit }, user) => commit('setUser', user),
  setToken: ({ commit }, token) => commit('setToken', token)
 }

const getters = {
  user: state => state.user,
  token: state => state.token,
  files: state => state.files
}

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

Then in your module:

import store from '@/store'
import { mapGetters } from 'vuex'

api.auth().onAuthStateChanged(function (user) {
  store.dispatch('setUser', user)    // .dispatch triggers ACTION, handling async evt
  if (user) {

  } else {

  }
})


export default {
  // mapGetters maps getters allowing this.user in script, or {{ user }} in template
  computed: mapGetters([
    'user',
    'files'
  ])
}

Upvotes: 3

Related Questions