2

Firebase Firestore prevent client side creation of fields in a document

As per the above link, this has been asked before, but not correctly answered.

I can't seem to figure out how to prevent a user from uploading garbage data to random field names in a document. Although it's easy to enforce rules about existing fields in your 'schema', I haven't found anything that can stop the user from updating a document with

const payload = {
 random123: 5,
 anotherRandom123: 5
}

I understand that it might be possible to count the total number of fields and limit those, however, if a document happens not to have every field populated, you could still write garbage data. You could even check for certain field names with the in operator and list functions. The only way I can imagine doing it is by forcing the document to always populate all the fields you might need, enforce a static number of fields and then check to ensure that every field name is present/correct.

This would not work if a document has optional fields.

Is this possible? What is the best way to solve this problem?

George43g
  • 565
  • 10
  • 20
  • 1
    You saying you want to write documents with not all fields populated in pre-defined keys and still check that whichever fields are written are from predefined keys? – ked Dec 19 '19 at 14:46
  • @ked yes that is correct! – George43g Dec 20 '19 at 01:31

1 Answers1

7

If you want to limit the names of the fields that could possibly be added to a document from the client app, you will need to examine request.resource.data, which is a Map of all the fields of the document to be written. Map has a keys property method which is returns a List all those field names. You can check that the List contains only the field names you want by using its hasOnly method:

allow write: if request.resource.data.keys().hasOnly(['a', 'b', 'c']);

This rule requires that clients can only make modifications to documents that use the named fields a, b, and c.

Note that if your backend ever includes additional keys, this rule will always fail for client writes, as request.resource.data contains the entire state of the final document being written, not just the fields that changed. That's a more complex problem, and there are other answers on Stack Overflow that deal with this more specific issue.

George43g
  • 565
  • 10
  • 20
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thank you so much Doug! This is spot on. I'm also interested in the caveat you provided - I imagine this used to be done with 'writeFields', although curious how it would be achieved now. PS: Thanks for your informative youtube vids on Firebase as well - they were a large part of my journey in learning different aspects of Firebase. – George43g Dec 20 '19 at 01:46
  • I just submitted an edit, because when I tried to implement this it seems that keys is a method, not a property! :) – George43g Dec 20 '19 at 05:37