Reputation: 3104
I have a problem with this Cloud Firestore security rule:
service cloud.firestore {
match /databases/{database}/documents {
match /stages/{stageId} {
match /collections/{collectionId} {
match /pois/{poiId} {
allow read;
allow write: if request.auth != null ||
request.method == "update" &&
request.resource.data.keys() == ["pm"];
}
}
}
}
}
In code I am trying to update the field pm
of an existing document as a non-authenticated user with a dictionary of values. The Firestore log shows this request:
2018-06-26 12:46:05.476997+0100 app[59292:3472939] 5.3.0 - [Firebase/Firestore][I-FST000001] FSTWriteStream 60c000107230 mutation request: <GCFSWriteRequest 0x60c0006e9e00>: {
writes {
update {
name: "projects/myApp/databases/(default)/documents/stages/dev/collections/ETzbIXBn0Z5FOsCHtHlv/pois/zJELKLTWupuMkYQNb9gl"
fields {
key: "pm"
value {
map_value {
fields {
key: "subLocality"
value {
string_value: "Albufeira"
}
}
fields {
key: "locality"
value {
string_value: "Albufeira"
}
}
fields {
key: "country"
value {
string_value: "Portugal"
}
}
fields {
key: "postalCode"
value {
string_value: "8200-142"
}
}
fields {
key: "adminArea"
value {
string_value: "Faro"
}
}
fields {
key: "timezone"
value {
string_value: "Europe/Lisbon"
}
}
fields {
key: "thoroughfare"
value {
string_value: "Rua Primeiro de Dezembro"
}
}
fields {
key: "name"
value {
string_value: "Rua Primeiro de Dezembro"
}
}
fields {
key: "isoCountryCode"
value {
string_value: "PT"
}
}
}
}
}
}
update_mask {
field_paths: "pm"
}
current_document {
exists: true
}
}
stream_token: "\031\020hB\002\201\364\265\265"
}
This request fails with "missing or insufficient permissions".
When I simulate an update
to stages/dev/collections/ETzbIXBn0Z5FOsCHtHlv/pois/zJELKLTWupuMkYQNb9gl
with this simulated data
{"__name__":"/databases/(default)/documents/stages/dev/collections/ETzbIXBn0Z5FOsCHtHlv/pois/zJELKLTWupuMkYQNb9gl","data":{"pm":{"adminArea":"Germany","testArea":"Munich"}}}
the simulator allows the update.
In my code (Swift project/iOS) I am using the updateData
method on an existing document reference.
As a parameter I am passing this array:
["pm": ["adminArea": "Faro", "name": "Rua Primeiro de Dezembro", "postalCode": "8200-142", "locality": "Albufeira", "subLocality": "Albufeira", "isoCountryCode": "PT", "timezone": "Europe/Lisbon", "thoroughfare": "Rua Primeiro de Dezembro", "country": "Portugal"]]
Any idea what I am doing wrong? Thanks!
Upvotes: 2
Views: 702
Reputation: 43
You can rewrite this
request.resource.data.keys() == ["pm"];
with
request.writeFields == ["pm"];
Upvotes: 0
Reputation: 3104
As it turns out
request.resource.data.keys() == ["pm"];
was not working as expected on deployment (even though it worked in the simulator).
Replacing it with
request.writeFields.size() == 1 && "pm" in request.writeFields;
did the trick for me.
Simulating rules is a great step towards a usable product (Hello Google: Debugging rules ???), but only if they work the same in the simulator as on a live deployment...
Upvotes: 4