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

问题描述 投票:0回答:4

我正在按照 vuegram 的说明使用 vuex 和 firebase 来实现用户身份验证。我尝试了很多方法来分离 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();

但是,上面的代码只是在 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
        }
    }
})

退出方法:

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

我的 firebase 规则:

allow read, write: if request.auth.uid!=null;
firebase google-cloud-firestore vuex
4个回答
6
投票

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

参见关于分离监听器的文档,当你附加监听器时,你首先得到一个取消订阅函数的引用:

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

然后在注销前调用该函数:

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

1
投票

如果您在许多页面上都有注销按钮,只需导航到不同的页面并从那里调用注销。这样你就不必用取消订阅来乱扔代码了。


0
投票

要摆脱

onsnapshot
权限被拒绝的错误,只需处理错误 (参见 Firestore 文档) 而无需在您的
firebase auth
:

上做任何事情
const unsubscribe = onSnapshot(
  collection(db, "cities"), 
  (snapshot) => {
    // ...
  },
  (error) => {
    // Handle your error here. It will not log in the console anymore,
    // and the listener has already been automatically detached at this point.
  });

报错后监听器会自动脱离,不用再调用

unsubscribe

出错后,监听器将不会再接收到任何事件,并且 无需分离您的听众。

所以只需用您的

firebase auth
注销您的用户,就好像它不知道您的
onsnapshot
听众一样。


-3
投票

您也可以查看您的

Firestore rules
.

如果这是那里的东西:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

改为:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

请注意,这是不安全的,仅用于开发目的。要了解 Firestore 规则的工作原理,请查看这个 youtube 视频

© www.soinside.com 2019 - 2024. All rights reserved.