For the life of me, I cannot understand why the following is resulting in a false
for allowing writes. Assume my users
collection is empty to start
This might seem like over kill but for updating documents where you might have other fields that are not user generated, eg. roles, created etc. you need functions that can test that those fields don't change. Hence meet these three FNs.
function hasOnlyFields(fields) {
if request.resource.data.keys().hasOnly(fields)
}
function hasNotChanged(fields) {
return (fields.size() < 1 || equals(fields[0]))
&& (fields.size() < 2 || equals(fields[1]))
&& (fields.size() < 3 || equals(fields[2]))
&& (fields.size() < 4 || equals(fields[3]))
&& (fields.size() < 5 || equals(fields[4]))
&& (fields.size() < 6 || equals(fields[5]))
&& (fields.size() < 7 || equals(fields[6]))
&& (fields.size() < 8 || equals(fields[7]))
&& (fields.size() < 9 || equals(fields[8]))
}
function equals(field) {
return field in request.resource.data && field in resource.data && request.resource.data[field] == request.resource.data[field]
}
So on update of say user document, where the user may only update their name, age, and address, but not roles and email you can do:
allow update: if hasOnlyFields(['name', 'age', 'address']) && hasNotChanged(['email', 'roles'])
Note the hasNotChanged can check up to 9 fields. Also these aren't the only checks you would want to do. You'd need to check the the types and ownership of the document as well.