Vuex 和 Firebase 存储状态错误

Posted

技术标签:

【中文标题】Vuex 和 Firebase 存储状态错误【英文标题】:Vuex and Firebase store state errors 【发布时间】: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
      )
    
  

【问题讨论】:

【参考方案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(...

以上是关于Vuex 和 Firebase 存储状态错误的主要内容,如果未能解决你的问题,请参考以下文章

Vuex 和 VueJS(不要在突变处理程序之外改变 vuex 存储状态)

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

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

Vue 路由器 Auth-guard 功能不检查 Vuex 存储状态

Vuex 突变引发错误 - 不要在突变处理程序之外改变 vuex 存储状态

vuex 错误 - 不要在突变处理程序之外改变 vuex 存储状态