Locking a document with firebase rules

Cristóbal Felipe Fica Urzúa

I have this set of rules in firestore

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
  
    match /{document} {
      allow read: if true;
      allow write: if isTrustworthy();
    }
    match /stores/{storeId}{
      match /{document} {
        allow read: if true;
        allow write: if isTrustworthy();
      }
      match /departures/{departureId} {
        allow read: if true;
        allow write: if !(resource.data.locked);
      }  
    }
        
    function isTrustworthy(){
      return isSignedIn() && emailVerified();
    }
    
    function isSignedIn() {
      return request.auth != null;
    }
    function emailVerified() {
      return request.auth.token.email_verified;
    }
  }
}

but I get an error when setting, updating or deleting in the departures path.

eg.

this.afs.collection('stores').doc(this.auth.store)
   .collection('departures')
   .doc(element.shipping.trackingNumber.toString())
   .set({"test":true})

the document is not existent, but it won't work neither if the document exist, independent of the parameter "locked" I got the following error:

ERROR Error: Uncaught (in promise): FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

FirebaseError: Missing or insufficient permissions.

What I need is that if the document has a parameter "locked" set to true, it cannot be deleted, updated, nor set with {merge:true} option.

any help will be much appreciated.

l1b3rty

There are a few issues with your rule and code:

  1. On create, resource.data does not exist
  2. On update or delete, it could be that the field locked does not exist
  3. When you use set to create or update a document in Firestore, you have to add the options {merge: true}, to update the document instead of overwriting it in case it already exists.

Try this instead:

  • Code:

    this.afs.collection('stores').doc(this.auth.store)
      .collection('departures')
      .doc(element.shipping.trackingNumber.toString())
      .set({"test":true}, {merge: true})
    
  • Rules:

    match /departures/{departureId} {
      allow read: if true;
      allow create: if true;
      allow update, delete: if !resource.data.get("locked", false);
    } 
    

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related