'Middleware getting called before getting authentication (Nuxt/Firebase)

I'm new at Nuxt and using it for my frontend and firebase as backend. The website uses SSR and I follow this documentation: https://firebase.nuxtjs.org/tutorials/ssr

My middleware should check if the user was logged in or logged out, if the user was logged in and try to access the sign-in page the middleware should redirect the user to bussnessInfo page, vice-versa the middleware should deny/re-direct access to other page if the user does not have credentials.

My Middleware:

export default function ({ store, route, redirect }) {
  if (store.getters.getEmail !== null && route.path === '/') {
    return redirect('/businessInfo')
  } else if (store.getters.getEmail === null && route.path !== '/') {
    return redirect('/')
  }
}

My logIn method:

  methods: {
    logIn () {
      // eslint-disable-next-line prefer-const
      let that = this
      this.$fire.auth.signInWithEmailAndPassword(this.auth.email, this.auth.password)
        .catch(function (error) {
          that.snackbarText = error.message
          that.snackbar = true
        }).then(async () => {
          await that.$router.push('/businessInfo')
        })
    }
  }

I'm trying to login but my middleware execute first before I got my credentials, I tried removing my middleware first to see if the problem was caused by nuxt.config but the authentication run smoothly without the middleware, so I put the code back into the middleware and added a console log of the user credentials inside the if statement

export default function ({ store, route, redirect }) {
  if (store.getters.getEmail !== null && route.path === '/') {
    console.info(store.state.authUser)
    return redirect('/businessInfo')
  } else if (store.getters.getEmail === null && route.path !== '/') {
    console.info(store.state.authUser)
    return redirect('/')
  }
}

I discover that after clicking the login button my middleware checks the credential first before the authUser receive it. Then if I click the login button again since I already have the token it will accept the user and redirect him to businessInfo.

Screenshot of the console

I think my mistake was something on the middleware but I dont know how to fix it.

In case anyone wants to see my state management:

Actions:

/* eslint-disable no-console */
export default {
  async nuxtServerInit ({ dispatch }, ctx) {
    // INFO -> Nuxt-fire Objects can be accessed in nuxtServerInit action via this.$fire___, ctx.$fire___ and ctx.app.$fire___'

    /** Get the VERIFIED authUser on the server */
    if (ctx.res && ctx.res.locals && ctx.res.locals.user) {
      const { allClaims: claims, ...authUser } = ctx.res.locals.user

      console.info(
        'Auth User verified on server-side. User: ',
        authUser,
        'Claims:',
        claims
      )

      await dispatch('onAuthStateChangedAction', {
        authUser,
        claims
      })
    }
  },

  async onAuthStateChangedAction ({ commit }, { authUser }) {
    if (!authUser) {
      commit('RESET_STORE')
      return
    }
    if (authUser && authUser.getIdToken) {
      try {
        const idToken = await authUser.getIdToken(true)
        console.info('idToken', idToken)
      } catch (e) {
        console.error(e)
      }
    }
    commit('SET_AUTH_USER', { authUser })
  },

  checkVuexStore (ctx) {
    if (this.$fire.auth === null) {
      const newLocal = 'Vuex Store example not working - this.$fire.auth cannot be accessed.'
      throw newLocal
    }

    alert(
      'Success. Nuxt-fire Objects can be accessed in store actions via this.$fire___'
    )
  }
}

Getters:

export default {
  isLoggedIn: (state) => {
    try {
      if (state.authUser.uid !== null) {
        return true
      }
    } catch {
      return false
    }
  },
  getEmail: (state) => {
    try {
      return state.authUser.email
    } catch {
      return null
    }
  }
}

Mutations:

import initialState from './state'

export default {
  RESET_STORE: (state) => {
    Object.assign(state, initialState())
  },

  SET_AUTH_USER: (state, { authUser }) => {
    state.authUser = {
      uid: authUser.uid,
      email: authUser.email
    }
  }
}

State:

export default () => ({
  authUser: null
})


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source