DEV Community

Building User Accounts with Nuxt, Vuex, and Firebase

Drew Clements on March 03, 2020

Recently, I was working to implement user accounts into my application I've been building with Nuxt as the frontend and Firebase for the backend/da...
Collapse
 
tully4school profile image
Joseph Tully

Love the detail and time you put into this. thank you so much!

Collapse
 
abelmoremi profile image
Abel Moremi

great article by the way... Oh Hi...

I was wondering how you implement firebase.js plugin with ENV variables... as you know to commit API keys is not a healthy practice. I have been trying it out with no luck and little insight to it would be really helpful. Thank you

Collapse
 
tb_95 profile image
TomBell_95

Did you manage to solve this issue? I am facing the same problem and the only solution would be to migrate the firebase config to nuxt.config.js ?

Collapse
 
drewclem profile image
Drew Clements

For this, you'd create a .env file and store your keys there. Then you'd setup your nuxt.config.js to use those variables as well.

From there, you'd use process.env.YOUR_KEY where you needed to access the key.

Thread Thread
 
tb_95 profile image
TomBell_95

Thanks for replying, I have been working on this for over a week and seems like this is the only fix so far: stackoverflow.com/questions/703036...

Thread Thread
 
drewclem profile image
Drew Clements

This kind of a gotcha with JAMstack sites and authentication, because at some level, the keys will be exposed somewhere within the compiled code.

However, using the .env and nuxt.config.js route will at least keep them out of the repo.

I haven't built anything with this setup that gets enough traffic to warrant going the extra mile for the extra security.

I don't know of a workaround for this.

Thread Thread
 
tb_95 profile image
TomBell_95

Completely agree, I have been struggling with this for a week and wanted to finish my app with the best practise but from looking at what the community is saying, its a common problem. Thanks mate.

Collapse
 
bobwinn profile image
Bob Winn

Thank you for taking the time on this article; I found it very helpful. Steve's comment from October 2020 was also a great addition. There are some things I have had to tweak as well and others might find this useful.

  1. This might be obvious, but just in case others might have missed this: in the onAuthStateChanged observer we not only have to point to an action rather than a mutation we also have to have "store.dispatch" instead of "store.commit."

  2. Nuxt allows you to organize your store with modular files -- so auth.js, posts.js, etc. If you do this, then you need to indicate the file name with the action. In my store, I have an auth.js file, so I have this in fireAuth.js:
    auth.onAuthStateChanged((user) => {
    store.dispatch('auth/setUser', user)
    resolve()
    })

  3. In the SET_USER mutation, I had to specify two different values for the payload to prevent the browser from crashing. Here’s what I did:

SET_USER(state, payload) {
if (payload === null) {state.user = payload}
if (payload !== null) {state.user = payload.uid}
},

If there is a user (i.e. payload !== null), you can of course grab whatever you want from payload to assign to state.user.

Collapse
 
drewclem profile image
Drew Clements

These are great points!

This article is actually due for an update, and these will definitely be included!

Collapse
 
tb_95 profile image
TomBell_95

Hi thanks for the above, how to we go about protecting the sensitive keys in the firebase config? From what I am seeing across stackoverflow and other forums is that you cannot use environment variables from plugins and would need to migrate the info over to nuxt.config?

Collapse
 
stevedl profile image
Steve • Edited

Firstly, great article this has been very helpful, however I have run into an issue, the following is causing "Do not mutate vuex store outside mutation handlers" error to appear infinitely and crashes my browser.

auth.onAuthStateChanged((user) => {

  store.commit('setUser', user) <-- the culprit
  resolve()
Enter fullscreen mode Exit fullscreen mode

})

My auth store (Using modules)
import { auth } from '~/plugins/firebase.js'

// state
export const state = () => ({
user: ''
})

export const getters = {
user (state) {
return state.user
},
isAuthenticated (state) {
return !!state.user
}
}

// mutations
export const mutations = {
SET_USER (state, user) {
state.user = user
}
}

// actions
export const actions = {
setUser ({ commit, store }, payload) {
commit('SET_USER', payload)
},
signUp ({ commit }, { email, password }) {
return auth.createUserWithEmailAndPassword(email, password)
},
signInWithEmail ({ commit }, { email, password }) {
return auth.signInWithEmailAndPassword(email, password)
},
signOut () {
return auth.signOut()
}
}

export const strict = false

Collapse
 
drewclem profile image
Drew Clements

Thanks for this, Steve!

It seems like this article is due for an update. This was written based off of some code that was originally written in 2018, so there are some practices (which is what you found) that aren't the 'best' anymore.

I'll put it on my to-do list to try and get this update this week. I'm sorry you ran into issues!

Collapse
 
seriouslee13 profile image
SeriousLee13

Cool article, but how do you prevent users from accessing pages that require authentication, as middleware runs only on server side on initial page load?

Collapse
 
drewclem profile image
Drew Clements

Great question! Perhaps I should update this article to include that.

In the meantime, you can check out this repo that does just that.
github.com/drewclem/Colt

Here is where middleware is set up
github.com/drewclem/Colt/blob/mast...
And here is how you would lock a page behind the authentication (see line 43)
github.com/drewclem/Colt/blob/mast...