I managed to make an authentication functionality, where the user can use:
Everything works good until I sign out. I use onSnapshot()
for the update functionality So everytime the auth state changes i set the returned data in the component's state.
firebase_auth.auth().onAuthStateChanged(user => {
if(user) {
firebase.collection('users').doc(user.uid).onSnapshot(doc => {
doc.exists && this.setState(prevState => ({ ...prevState, user_data: doc.data() }));
});
} else this.setState(prevState => ({ ...prevState, user_data: null }));
});
signOut() {
firebase.auth().signOut();
}
When i sign out the following error occurs:
Uncaught Error in onSnapshot: FirebaseError: Missing or insufficient permissions.
Here are my database rules. I use firebase cloud storage .
service cloud.firestore {
match /databases/{database}/documents {
match /users/{uid} {
allow read, write: if request.auth.uid == uid
}
}
}
And if i stop the onSnapshot listener
, not even the log in
will work.
firebase_auth.auth().onAuthStateChanged(user => {
if(user) {
const unsubscribe = firebase.collection('users').doc(user.uid).onSnapshot(doc => {
doc.exists && this.setState(prevState => ({ ...prevState, user_data: doc.data() }));
});
unsubscribe();
} else this.setState(prevState => ({ ...prevState, user_data: null }));
});
It seems your Firestore security rules requite that the user is authenticated to read certain data. For that reason, the listener(s) for that data get rejected when you sign the user out.
The solution to prevent the error message, is to remove the listeners yourself in your code before signing the user out. So keep the unsubscribe
in a field in the object where you can reach it from signOut()
, and then:
signOut() {
unsubscribe();
firebase.auth().signOut();
}
So the fix for this problem is:
firebase_auth.auth().onAuthStateChanged(user => {
if(user) {
const unsubscribe = firebase.collection('users').doc(user.uid).onSnapshot(doc => {
doc.exists && this.setState(prevState => ({ ...prevState, user_data: doc.data() }));
});
this.setState(prevState => ({ ...prevState, unsubscribe });
} else this.setState(prevState => ({ ...prevState, user_data: null }));
});
I set the unsubscribe
function in the state
, and use it later in the sign out
:
signOut() {
this.state.unsubscribe();
firebase.auth().signOut();
}
Thank you frank .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.