我正在按照 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;
由于您在注销时仍然有一个活动的侦听器,系统检测到客户端已失去读取该数据的权限并拒绝该侦听器。这意味着您需要在注销之前删除侦听器以防止出现错误消息。
参见关于分离监听器的文档,当你附加监听器时,你首先得到一个取消订阅函数的引用:
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);
});
}
如果您在许多页面上都有注销按钮,只需导航到不同的页面并从那里调用注销。这样你就不必用取消订阅来乱扔代码了。
要摆脱
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
听众一样。
您也可以查看您的
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 视频。