Reputation: 241
My security roles are ignored when using onSnapShot - I'm getting all the documents in the collection and not only the user objects.
roles:
service cloud.firestore {
match /databases/{database}/documents {
match /story/{mid} {
function memberOf() {
return resource.data.creator && request.auth.uid == resource.data.creator;
}
allow list: if request.query.limit <= 1000 &&
memberOf();
allow get,read : if memberOf();
allow write: if request.auth.uid == resource.data.creator;
}
}
}
and my code is in react-native-firebase on Android: "react-native-firebase": "^4.3.8", "com.google.firebase:firebase-firestore:17.1.0"
ctor:
this.ref = firebase.firestore().collection('story');
componentDidMount() {
this.unsubscribeDate = this.ref.onSnapshot(this.onCollectionUpdate);
}
componentWillUnmount() {
this.unsubscribeDate();
}
onCollectionUpdate = querySnapshot => {
//console.log('onCollectionUpdate', querySnapshot);
querySnapshot.forEach(doc => {
const { title, complete } = doc.data();
console.log('onCollectionUpdate doc', title);
});
};
ref docs: role based access roles query
Upvotes: 1
Views: 1242
Reputation: 163
This behavior a bug. I get the same, using javascript with PWA.
I was doing tests and I noticed that the problem happens when using persistence in firestore. When using onSnapshot, this is executed 2 times when starting it, if I deactivate the persistence of firestore the answer is empty, as expected, but with persistence enabled the result of the cache is shown, then the update of the onSnapshot event is executed, but since the reading is denied by a rule in the google console, it does not update the result by means of the event (onCollectionUpdate), so you are reading data that should not be displayed.
This happens when there is data in cache previously, if it is the first time that the application is used in the device, the rule works perfectly, because there is no data in cache previously. I consider this behavior a bug, because it should respect the rule even with the cache, knowing that it seeks to restrict the reading of documents.
To print the error on onSnapshot:
componentDidMount() {
this.unsubscribeDate = this.ref.onSnapshot(this.onCollectionUpdate, this.onErrorUpdate);
}
onErrorUpdate = error => {
console.log(error);
};
Upvotes: 2