I'm using vuex and firebase to implement user authentication following the instruction of vuegram. I tried many ways to detach firebase listeners, the only one that stop warning error is the following:
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();
However, the code above just stop warning on signOut(), I can't update data anymore.
My store.js file:
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
}
}
})
The signOut method:
signOut: function(){
fb.auth.signOut().then(()=> {
this.$store.dispatch('clearData')
this.$router.push('login')
}).catch(function(error) {
console.log(error);
});
}
My firebase rule:
allow read, write: if request.auth.uid!=null;
Since you still have an active listener when you log out, the system detects that the client has lost permission to read that data and rejects the listener. This means you need to remove the listener before signing out to prevent the error message.
See the documentation on detaching listeners, you first get a reference to the unsubscribe function when you attach the listener:
unsubscribe = fb.usersCollection.doc(user.uid).onSnapshot(doc => {
store.commit('setUserProfile', doc.data())
})
And then call that function before signing out:
signOut: function(){
unsubscribe();
fb.auth.signOut().then(()=> {
this.$store.dispatch('clearData')
this.$router.push('login')
}).catch(function(error) {
console.log(error);
});
}
If you have a logout button on many pages just navigate to a different page and call logout from there. Then you don't have to litter your code with unsubscribes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With