Nuxt.js: Check logged user in firebase with middleware

Created on 26 Jul 2017  路  14Comments  路  Source: nuxt/nuxt.js

I've built some auth middleware:

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.

Most helpful comment

I know that the Promise is freezing your app, the question is if onAuthStateChanged is never called, the promise is never resolved so it's normal.

I believe that it should not be a middleware but a plugin @lukasborawski

plugins/auth.js

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

export default function ({store, router}) {
  api.auth().onAuthStateChanged((user) => {
     store.commit('SET_USER', user)
  })
}

in your nuxt.config.js:

module.exports = {
  plugins: ['~/plugins/auth.js']
}

Then you can have a middleware to check if store.state.user exists, and if not, redirect to /login for example.

it should work with 1.0.0-rc3 since you can have access to context in your plugins by exporting a function.

All 14 comments

It's hard to tell whats going on here because we don't know whats in your api.js file.

But from what I gather, you're doing an API request every time you want to get information about your current auth state. This is not the best way of doing things. You want to check auth state once, and save the result of that in the store.

Once you have that type of setup, all you'd need to do in your middleware is check the current auth state in your store

export default function ({ store, error }) {
  if (!store.state.authUser) {

  }
}

The example isn't using firebase, but may be helpful to you: https://nuxtjs.org/examples/auth-routes/

Also check @nuxtjs/auth and @nuxtjs/axios in community modules

@ChavaSobreyra ok, the way that i'm using store is a second party thing, right now i can't resolve Firebase request. I think this must be a Promise before the compiler will go further. So when i'm doing this the Promise never finish. My example for now:

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

export default function ({store, router}) {
  return new Promise((resolve, reject) => {
    api.auth().onAuthStateChanged((user) => {
      if (user) {
        store.state.user = user
        resolve(user)
      } else {
        reject(Error('It broke'))
      }
    })
  })
}

What is wrong? @Atinux maybe you can help?

Hi @lukasborawski

Can you print a console.log inside the callback of onAuthStateChanged to make sure it's called by Firebase?

@Atinux well i can pass new value to this store object (e.g. store.state.user = 'test') but i can't reach user object from FB. And just like i've said the promise freezing my app.

I know that the Promise is freezing your app, the question is if onAuthStateChanged is never called, the promise is never resolved so it's normal.

I believe that it should not be a middleware but a plugin @lukasborawski

plugins/auth.js

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

export default function ({store, router}) {
  api.auth().onAuthStateChanged((user) => {
     store.commit('SET_USER', user)
  })
}

in your nuxt.config.js:

module.exports = {
  plugins: ['~/plugins/auth.js']
}

Then you can have a middleware to check if store.state.user exists, and if not, redirect to /login for example.

it should work with 1.0.0-rc3 since you can have access to context in your plugins by exporting a function.

@Atinux but from which place i should call the plugin before my page/component will be rendered?

When do you need to call api.auth()?

@Atinux just before render the page, i want to present private/public content. So the middleware is perfect for this.

@Atinux OK, i've used the plugin for this, and it seems to work fine, but when i'm doing the redirect i have an error: ERR_TOO_MANY_REDIRECTS, my code for now:

import api from '~/api/Api.js'
import { getUser } from '~/api/AuthService'

export default function ({store, redirect}) {
  if (store.getters.loggedUser) {
    return
  } else {
    if (getUser()) {
      store.commit('SET_USER', getUser())
    } else {
      api.auth().signOut()
      redirect('/auth/signup')
    }
  }
}

What is wrong?

OK, upgreade to 1.0.0.rc-3 solved this issue.

Hey @lukasborawski, same issue for me, can you please share with us your code in api folder ? Thanks a lot

Is there a way to re-run the middleware? For example, if I have this middleware:

export default function ({ store, redirect }) {
  if (!store.getters['user/isAuthenticated']) {
    return redirect('/login')
  }
}

Imagine there is logout button in the header which when clicked triggers a mutation and will subsequently update the value of store.getters['user/isAuthenticated'], in this case, the middleware won't be re-run and the user will stay on the current auth protected page.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maicong picture maicong  路  3Comments

vadimsg picture vadimsg  路  3Comments

uptownhr picture uptownhr  路  3Comments

surmon-china picture surmon-china  路  3Comments

jaredreich picture jaredreich  路  3Comments