8
votes

I need some help making my security rules for firestore work.

These are my firestore rules:

service cloud.firestore {
  match /databases/{database}/documents {
     match /orders/{orderID} {
       allow read, update: if  request.auth.uid == resource.data.buyerId  || request.auth.uid == resource.data.sellerId;
    }
  }
}

my orders collection:

orders: {
sellerId: 'some-id',
createdAt: timestamp,
buyerId: 'some-id'
}

It should return all documents from orders collection which has either buyerId or sellerId equal to authorised user (request.auth.uid).

but the above rule is not working as expected.

firestore collections screenshot

firebase simulator output

2
What is the exact query you are using to fetch the documents?Renaud Tarnec
I am testing it in firebase simulator and getting - Error running simulation — Error: simulator.rules line [4], column [52]. Null value error.Mohd Imran
Do you mean you are querying for all the documents of the orders collection? Could you add a print screen of the simulator?Renaud Tarnec
I have added firebase simulator outputMohd Imran

2 Answers

8
votes

That error message is suggesting that the requested document was not actually present in the database. You entered "orders/{orderId}", which looks like you put a wildcard in the Location field in the simulator. That's not going to work. You need to enter the path to an actual document that exists if you want to test your rule that uses its field values.

5
votes

resource.data: Null - this error happens when you try to create a new entity.

Split write rule, on create and update.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /user/{userId} {
      allow read: if request.auth.uid == userId;

      function authed() {
        return request.auth.uid == userId;
      }
      allow create: if authed() && request.resource.data.keys().hasOnly(['name']);
      allow update: if authed() && request.resource.data.diff(resource.data).changedKeys().hasOnly(['name']);
      allow delete: if authed();
    }
  }
}