使用 Nuxt、Laravel API 和 Firebase Auth 将用户 uid 传递到我的数据库的正确方法?

Proper way to pass user uid to my database with Nuxt, Laravel API and Firebase Auth?

我想做什么

我目前正在使用 Nuxt、LaravelAPI 和 Firebase 身份验证创建餐厅预订网络应用程序。

我想做的是,

  1. 在 Firebase 身份验证中创建一个新的用户帐户。

    {
        "email": "User's email address from input",
        "password": "User's password from input"
    }
    
  2. 同时,在我的本地数据库中插入一个新的用户账号,密码为用户uid。

    {
        "name": "User's name from input",
        "email": "User's email address from input",
        "password": "User's uid from store/auth.js"
    }
    

问题

Firebase Auth 注册成功,如果没有 uid,也注册到本地数据库。 但是当我尝试添加 uid 时,我在 Laravel 日志中收到此错误。

1364 Field 'General error: password' doesn't have a default value

我以为是异步处理导致的这个错误,所以在代码中加入了Async,但是结果并没有改变。

代码

// register.vue
<script>
import firebase from '~/plugins/firebase'

export default {
  layout: 'auth',
  data () {
    return {
      user: {
        name: null,
        email: null,
        password: null,
      }
    }
  },
  methods: {
    async register() {
      this.$store.dispatch('auth/register',
        {
          name: this.user.name,
          email: this.user.email,
          password: this.user.password
        }
      )
      .then(() => {
        this.$store.dispatch('auth/onAuth')
      })
      .then(() => {
        this.$axios.post('http://localhost:8000/api/v1/users',
          {
            name: this.user.name,
            email: this.user.email,
            password: this.$store.state.auth.userUid
          }
        )
      })
      .then(() => {
        this.$router.push('/thanks')
      })
    },
  }
}
</script>

// store/auth.js

import firebase from '~/plugins/firebase.js'

export const state = () => ({
    userUid: '',
    userEmail: '',
    loggedIn: false,
})

export const actions = {
    async register({ commit }, payload) {
        firebase
            .auth()
            .createUserWithEmailAndPassword(payload.email, payload.password)
        .then((result) => {
            const user = result.user
            commit('loginStatusChange', true)
            console.log('Regist a user was successful')
            commit('setUserUid', user.uid)
            commit('setUserEmail', user.email)
        })
    },

    onAuth({ commit }) {
        firebase.auth().onAuthStateChanged(user => {
            user = user ? user : {}
            commit('setUserUid', user.uid)
            commit('setUserEmail', user.email)
            commit('loginStatusChange', user.uid ? true : false)
        })
    }
}

export const mutations = {
    loginStatusChange(state, status) {
        state.loggedIn = status
    },
    setUserUid(state, userUid) {
        state.userUid = userUid
    },
    setUserEmail(state, userEmail) {
        state.userEmail = userEmail
    }
}

export const getters = {
    getUserUid(state) {
        return state.userUid
    },
    getUserEmail(state) {
        return state.userEmail
    }
}

环境

问题是您的操作不是 composable,因此您对 Laravel 的 Axios post 请求不会等待前两个操作完成,因此 this.$store.state.auth.userUid 在那个阶段是空的。

  1. 让你的异步操作 return 一个实际等待事情完成的承诺。

    export const actions = {
      async register({ commit }, { email, password }) {
        const { user } = await firebase //  note the "await" here
            .auth()
            .createUserWithEmailAndPassword(email, password)
    
        commit('loginStatusChange', true)
        console.log('Register a user was successful')
        commit('setUserUid', user.uid)
        commit('setUserEmail', user.email)
    
        return user //  return the user so consumers can use it
      }
    }
    
  2. 注册一个 firebase 身份验证状态更改侦听器不应该配置为 Vuex 操作。我会 register this as a plugin

    // store/index.js
    import firebase from "~/plugins/firebase"
    
    const authStateChangePlugin = store => {
      firebase.auth().onAuthStateChanged(user => {
        user = user ? user : {}
        store.commit("auth/setUserUid", user.uid)
        store.commit("auth/setUserEmail", user.email)
        store.commit("auth/loginStatusChange", user.uid ? true : false)
      })
    }
    
    export const plugins = [ authStateChangePlugin ]
    
  3. 在 post发送到 Laravel

    之前等待您的操作发送
    methods: {
      async register () {
        //  note the use of "await"
        const user = await this.$store.dispatch("auth/register", { 
          ...this.user
        })
    
        await this.$axios.post("http://localhost:8000/api/v1/users", {
          ...this.user,
          password: user.uid // no need to reference the store here
        })
    
        this.$router.push('/thanks')
      }
    }