【问题标题】:Vuex and Firebase store state errorsVuex 和 Firebase 存储状态错误
【发布时间】:2017-09-05 19:26:40
【问题描述】:

我的 vuex 商店中有以下设置:我的用户使用 Firebase 身份验证登录。登录后,firebase.auth().onAuthStateChanged 被调用,user 设置为 state.user,但也保存在 Firebase 数据库中。当我添加代码的最后一部分 (database.ref...) 时,我的控制台因错误而爆炸。但是,这些错误与 Firebase 无关,而是与 Vuex 相关。

错误如下(x80):

[Vue 警告]:观察者“function () { return this._data.$$state }”的回调出错:

错误:[vuex] 不要在突变处理程序之外改变 vuex 存储状态。

我的代码仍然可以工作,但是在开发过程中,我不想在用户登录时看到 80 个错误。我怎样才能摆脱这些错误?

// actions
const actions = {
  startListeningToAuth ({ commit }) {
    firebase.auth().onAuthStateChanged((user) => {
      commit(types.SET_USER, { user })
    })
  }
}

// mutations
const mutations = {
  [types.SET_USER] (state, { user }) {
    state.user = user

    if (user) {
      database.ref('users/' + user.uid).set({
        name: user.displayName,
        email: user.email,
        photo_url: user.photoURL
      })
    }
  }
}

【问题讨论】:

    标签: javascript firebase firebase-realtime-database vue.js vuex


    【解决方案1】:

    您可以使用 toJSON() 方法到 firebase.User 界面

    commit(types.SET_USER, { user.toJSON() })
    

    这将允许在没有警告的情况下将用户数据添加到您的商店,但我想您可能会从 firebase 丢失实时用户状态。

    https://firebase.google.com/docs/reference/js/firebase.User#toJSON

    【讨论】:

      【解决方案2】:

      注册后要设置用户数据吗? 这是我执行此操作的代码

      firebase.auth().createUserWithEmailAndPassword(email, password)
                      .then((user) => {
                          //init user
                          userRef.child(user.uid).set({
                              email: email,
                              //Other data 
                          });
                      })
                      .catch((error) => {
                          state.isRegenter code hereister = false;
                          console.log(error);
      });
      

      【讨论】:

        【解决方案3】:

        突变应该只包含直接影响 vuex state 的代码。

        您收到错误是因为database.ref() 很可能以某种方式修改了user 对象。在您的突变中,state.user = user 使您的 state.user 对象引用与您的 user 变量相同的对象。所以,如果 user 在突变之外发生变化,状态也会发生变化,Vue 会骂你。

        您应该将您的 database.ref() 调用移至相关的操作方法,然后提交突变。由于database.ref() 是异步的,因此您需要等待该方法完成后再提交突变:

        // actions
        const actions = {
          startListeningToAuth ({ commit }) {
            firebase.auth().onAuthStateChanged((user) => {
              if (user) {
                database.ref('users/' + user.uid).set({
                  name: user.displayName,
                  email: user.email,
                  photo_url: user.photoURL
                }).then(() => {
                  commit(types.SET_USER, { user })
                })
              }
            })
          }
        }
        
        // mutations
        const mutations = {
          [types.SET_USER] (state, { user }) {
            state.user = user
          }
        }
        

        【讨论】:

        • database.ref 是异步调用吗?
        • 是的,它是异步的
        • @user3178862 好的,您需要等待通话结束。查看我的更新答案
        • 它显然帮助我解决了这个问题,但仍然没有完全删除它。现在它们只出现一次,而不是像 80 次那样调用错误。
        • onAuthStateChanged 也是异步的吗?如果是这样,请在 onAuthStateChanged() 之后尝试.then(() => { commit(...
        猜你喜欢
        • 1970-01-01
        • 2021-11-29
        • 2020-09-06
        • 1970-01-01
        • 2020-03-30
        • 2023-03-09
        • 1970-01-01
        • 2018-10-12
        • 2019-01-03
        相关资源
        最近更新 更多