Liron Sher
Liron Sher

Reputation: 241

Cloud firestore security rules are ignored when using the function onSnapshot

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

Answers (1)

Julian Vizcaino
Julian Vizcaino

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

Related Questions