Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore Rules to restrict write access to a specific field in a document

I am using Stripe for payments. For this, I have the following data model in Firestore:

Users/{userId}/payments/{document}

each {document} is an object that looks like:

{
  amount: 55
  token: {...}
  charge: {...}
}

Users must be able to to write the token field (this is what gets passed to the server), but I don't want users to be able to write the charge field.

Currently my rules allow any user to read and write to this document:

match /payments/{documents} {
  allow read, write: if request.auth.uid == userId;
}

What Firestore Rules will achieve my desired security?

like image 772
astrojams1 Avatar asked Jan 18 '18 05:01

astrojams1


People also ask

How do I write a rule for firestore?

To set up and deploy your first set of rules, open the Rules tab in the Cloud Firestore section of the Firebase console. Write your rules in the online editor, then click Publish.

How do you make a field unique in Firebase?

If you need some value (or combination of values) to be unique, you need to create a node that contains that value (or combination) as its key. If you need to guarantee that multiple values (or combinations) are unique, you'll need multiple of such nodes.

What is a Subcollection in firestore?

A subcollection is a collection associated with a specific document. Note: You can query across subcollections with the same collection ID by using Collection Group Queries. You can create a subcollection called messages for every room document in your rooms collection: collections_bookmark rooms. class roomA.

How do you use firestore playground rules?

Use the Rules PlaygroundOpen the Firebase console and select your project. Then, from the product navigation, do one of the following: Select Realtime Database, Cloud Firestore, or Storage, as appropriate, then click Rules to navigate to the Rules editor.


2 Answers

I believe something along the following would work, it allows clients to update fields except for charge, as well as create documents that don't have the charge field.

service cloud.firestore {   match /databases/{database}/documents {     function valid_create() {         return !(request.resource.data.keys().hasAll(["charge"]));     }      function valid_update() {         return request.resource.data.charge == resource.data.charge                || (valid_create()                   && !(resource.data.keys().hasAll(["charge"])))     }      match /payments/{userId} {         allow read: if request.auth.uid == userId;         allow create: if request.auth.uid == userId                         && valid_create();          allow update: if request.auth.uid == userId                         && valid_update();      }   } } 
like image 114
Dan McGrath Avatar answered Sep 23 '22 11:09

Dan McGrath


Set type was announced, along with some other cool stuff.


Using Sets to ensure that a document only has fields "a", "b", and "c":

request.resource.data.keys().toSet() == ["a", "b", "c"].toSet()

Similarly, you could make sure that a document only has specified keys, but not others:

(request.resource.data.keys().toSet() - ["required","and","opt","keys"].toSet()).size == 0?`
like image 37
m.spyratos Avatar answered Sep 22 '22 11:09

m.spyratos