onSnapshot 中未捕获的错误:错误:signOut() 上的权限缺失或不足

Jac*_*ack 5 firebase vuex google-cloud-firestore

我正在使用 vuex 和firebase按照vuegram的说明实现用户身份验证。我尝试了很多方法来分离 firebase 侦听器,唯一停止警告错误的方法如下:

var unsubscribe=fb.auth.onAuthStateChanged(user=>{
    if(user){
        store.commit('setCurrentUser',user)
        store.dispatch('fetchUserProfile')

        fb.usersCollection.doc(user.uid).onSnapshot(doc => {
            store.commit('setUserProfile', doc.data())
        })
    }
})
unsubscribe();
Run Code Online (Sandbox Code Playgroud)

但是,上面的代码只是停止对 signOut() 发出警告,我无法再更新数据。

我的 store.js 文件:

var unsubscribe=fb.auth.onAuthStateChanged(user=>{
    if(user){
        store.commit('setCurrentUser',user)
        store.dispatch('fetchUserProfile')

        fb.usersCollection.doc(user.uid).onSnapshot(doc => {
            store.commit('setUserProfile', doc.data())
        })
    }
})

export const store=new Vuex.Store({
    state:{
        currentUser:null,
        userProfile:{}
    },
    actions:{
        clearData({commit}){
            commit('setCurrentUser',null)
            commit('setUserProfile', {})
        },
        fetchUserProfile({ commit, state }) {
             fb.usersCollection.doc(state.currentUser.uid).get().then(res => {
                commit('setUserProfile', res.data())

            }).catch(err => {
                console.log(err)
            })
        },
        updateProfile({ commit, state }, data) {
            let displayName = data.displayName

            fb.usersCollection.doc(state.currentUser.uid).set({
                displayName: displayName
            }, {merge:true}).then(function() {
                alert("Document successfully written!");
            })
            .catch(function(error) {
                alert("Error writing document: ", error);
            });
        }
    },
    mutations:{
        setCurrentUser(state, val) {
            state.currentUser = val
        },
        setUserProfile(state, val) {
            state.userProfile = val
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

签出方法:

signOut: function(){
        fb.auth.signOut().then(()=> {
            this.$store.dispatch('clearData')
            this.$router.push('login')
        }).catch(function(error) {
            console.log(error);
        });
    }
Run Code Online (Sandbox Code Playgroud)

我的火力点规则:

allow read, write: if request.auth.uid!=null;
Run Code Online (Sandbox Code Playgroud)

Fra*_*len 5

由于您在注销时仍有一个活动侦听器,因此系统检测到客户端已失去读取该数据的权限并拒绝该侦听器。这意味着您需要在注销之前删除侦听器以防止出现错误消息。

请参阅有关分离侦听器文档,当您附加侦听器时,您首先会获得对取消订阅功能的引用:

unsubscribe = fb.usersCollection.doc(user.uid).onSnapshot(doc => {
    store.commit('setUserProfile', doc.data())
})
Run Code Online (Sandbox Code Playgroud)

然后在退出之前调用该函数:

signOut: function(){
    unsubscribe();
    fb.auth.signOut().then(()=> {
        this.$store.dispatch('clearData')
        this.$router.push('login')
    }).catch(function(error) {
        console.log(error);
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 在注销之前必须删除侦听器是荒谬的。它应该在注销时隐式显示,一旦 Firestore 实例知道您需要签名哪些实例,并且未经许可就不可能访问其中之一。注销应该自动取消订阅所有这些,因此您必须跟踪每个快照事件......现在想象一下在像我这样的大型应用程序上。没有意义 (2认同)
  • 当侦听器失去对底层数据的访问权限时,它会自动取消。为了确保您意识到这种情况的发生,这会引发已取消的侦听器的错误事件。 (2认同)