Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does resource.data.size() work in firestore rules (what is being counted)?

TLDR: What is request.resource.data.size() counting in the firestore rules when writing, say, some booleans and a nested Object to a document? Not sure what the docs mean by "entries in the map" (https://firebase.google.com/docs/reference/rules/rules.firestore.Resource#data, https://firebase.google.com/docs/reference/rules/rules.Map) and my assumptions appear to be wrong when testing in the rules simulator (similar problem with request.resource.data.keys().size()).


Longer version: Running into a problem in Firestore rules where not being able to update data as expected (despite similar tests working in the rules simulator). Have narrowed down the problem to point where can see that it is a rule checking for request.resource.data.size() equaling a certain number.

An example of the data being passed to the firestore update function looks like

 Object {
   "parentObj": Object {
     "nestedObj": Object {
       "key1": Timestamp {
         "nanoseconds": 998000000,
         "seconds": 1536498767,
       },
     },
   },
   "otherKey": true,
 }

where the timestamp is generated via firebase.firestore.Timestamp.now(). This appears to work fine in the rules simulator, but not for the actual data when doing

let obj = {}
obj.otherKey = true
// since want to set object key name dynamically as nestedObj value,
// see https://stackoverflow.com/a/47296152/8236733
obj.parentObj = {} // needed for adding nested dynamic keys
obj.parentObj[nestedObj] = {
    key1: fb.firestore.Timestamp.now()
}

firebase.firestore.collection('mycollection')
.doc('mydoc')
.update(obj)

Among some other rules, I use the rule request.resource.data.size() == 2 and this appears to be the rules that causes a permission denied error (since commenting out this rules get things working again). Would think that since the object is being passed with 2 (top-level) keys, then request.resource.data.size()=2, but this is apparently not the case (nor is it the number of keys total in the passed object) (similar problem with request.resource.data.keys().size()). So there's a long example to a short question. Would be very helpful if someone could clarify for me what is going wrong here.

like image 432
lampShadesDrifter Avatar asked Dec 24 '22 04:12

lampShadesDrifter


1 Answers

From my last communications with firebase support around a month ago - there were issues with request.resource.data.size() and timestamp based security rules for queries.

I was also told that request.resource.data.size() is the size of the document AFTER a successful write. So if you're writing 2 additional keys to a document with 4 keys, that value you should be checking against is 6, not 2.

Having said all that - I am still having problems with request.resource.data.size() and any alternatives such as request.resource.size() which seems to be used in this documentation https://firebase.google.com/docs/firestore/solutions/role-based-access

I also have some places in my security rules where it seems to work. I personally don't know why that is though.

like image 156
Dore mee Avatar answered Apr 19 '23 07:04

Dore mee