Search code examples
firebasevuejs2firebase-authenticationes6-promisevuex

Vue Vuex Firebase Auth email sign in and update username


I've got firebase auth setup, however, I'm trying to update username before setting that to my current state. When I run everything before the update, everything works fine, but I dont have a username. I'm fairly new with js promises so I've tried running the function and returning the function, neither have really worked. My expectation is that by the time the dashboard screen shows, that the username is set.

Below is the code for signup via email which works without username.

store/user/index.js

signUserUp ({commit}, payload) {
  commit('setLoading', true)
  commit('clearError')
  firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
    .then(function (user) {
      return user.updateProfile({
        displayName: payload.username
      })
    })
    .then(
      profile => {
        commit('setLoading', false)
        const newUser = {
          id: profile.uid,
          name: profile.username,
          email: profile.email,
          photoUrl: profile.photoURL
        }
        commit('setUser', newUser)
      }
    )
    .catch(
      error => {
        commit('setLoading', false)
        commit('setError', error)
        console.log(error)
      }
    )
}

This is the code that returns an error and does not update the username until I refresh.

signUserUp ({commit}, payload) {
  commit('setLoading', true)
  commit('clearError')
  firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
    .then(function (user) {
        return user.updateProfile({
          displayName: payload.username
        })
    .then(
      profile => {
        commit('setLoading', false)
        const newUser = {
          id: profile.uid,
          name: payload.username,
          email: profile.email,
          photoUrl: profile.photoURL
        }
        commit('setUser', newUser)
      }
    )
    .catch(
      error => {
        commit('setLoading', false)
        commit('setError', error)
        console.log(error)
      }
    )
},

My view is really simple just displaying the data.

<template>
  <div>
    <h1>Dashboard</h1>
    <button @click="onLogout">Logout</button>
    <hr>
    <app-alert v-if="error" @dismissed="onDismissed" :text="error.message"></app-alert>
    <img :if="user.photoURL" :src="user.photoUrl">
    <h4><b>Display Name :</b> {{ user.name }}</h4>
    <h4><b>Email :</b> {{ user.email }}</h4>
    <h4><b>Email Verified :</b> {{ user.emailVerified }}</h4>
    <h4><b>User ID :</b> {{ user.id }}</h4>
  </div>
</template>

<script>
export default {
  date () {
    return {}
  },
  computed: {
    user () {
      return this.$store.getters.user
    },
    error () {
      return this.$store.getters.error
    }
  },
  methods: {
    onLogout () {
      this.$store.dispatch('logout')
      this.$router.push('/')
    },
    onDismissed () {
      this.$store.dispatch('clearError')
    }
  }
}
</script>

The errors I get back are an alert that states

Cannot read property 'uid' of undefined

And also, username does not display on the page component, even though it does display on page refresh.

Everything works fine up until I add this bit to try and update the username on user create, so this little bit doesn't pass the new updated user object.

.then(function (user) {
  return user.updateProfile({
    displayName: payload.username
  })
})

Solution

  • Looks like my problem was in how I was sequencing my functions, in place of returning the user.updateProfile function, I was able to nest my updateProfile call like below, additionally, I was calling username as the object username when it should've been displayName.

    signUserUp ({commit}, payload) {
      commit('setLoading', true)
      commit('clearError')
      firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
        .then(function (user) {
          user.updateProfile({
            displayName: payload.username
          }).then(
            () => {
              commit('setLoading', false)
              const newUser = {
                id: user.uid,
                name: user.displayName,
                email: user.email,
                emailVerified: user.emailVerified
              }
              commit('setUser', newUser)
            }
          ).catch(
            error => {
              commit('setLoading', false)
              commit('setError', error)
              console.log(error)
            }
          )
        })
        .catch(
          error => {
            commit('setLoading', false)
            commit('setError', error)
            console.log(error)
          }
        )
    },