В правилах безопасности нет явного способа проверки происходящего обновления.Но то, что вы можете сделать, это проверить данные в документе до и после операции записи.Сравнивая эти два и зная, какие поля может содержать документ, вы можете убедиться, что только определенные поля могут быть обновлены.
Я часто использую эту маленькую вспомогательную функцию в моих правилах безопасности:
function isUnmodified(key) {
return request.resource.data[key] == resource.data[key]
}
Как следует из его названия, он гарантирует, что определенный ключ / поле не будет изменено в этом запросе на запись.Например, это правило тогда позволяет только пользователю обновлять свой документ профиля, если они не изменяют поле name
(если они не администратор):
allow update: if isAdmin(request) ||
(request.auth.uid == uid && isUnmodified(request, resource, 'name'));
У меня также естьэта вспомогательная функция, которая проверяет, существует ли определенное поле:
function isNotExisting(key) {
return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
}
Это важно, потому что иногда вы хотите разрешить, чтобы поле было записано только один раз, или разрешить его обновление только в том случае, если оно уже существует,Иногда я использую isNotExisting
для этого, но в эти дни я все больше и больше использую более детальные действия (create
, update
) по сравнению с совокупным правилом write
.
Наконец, вам могут потребоваться определенные поля, как в этом правиле создания:
allow create: if request.auth.uid == uid &&
request.resource.data.keys().hasOnly(['lastIndex', 'lastUpdated']) &&
request.resource.data.keys().hasAll(['lastIndex', 'lastUpdated'])
Таким образом, пользователь может создать документ профиля только в том случае, если он указывает поля lastIndex
и lastUpdated
.Если они укажут какие-либо дополнительные поля или укажут меньше полей, создание будет отклонено.
Теперь, имея это знание, мы можем вернуться к вашему требованию и посмотреть, как его реализовать.Как было сказано ранее, вам нужно будет сделать заявление по каждому отдельному полю, без подстановочных знаков.Поэтому, если в вашем документе есть три поля (field1
, field2
и field3
), которые должны существовать, и пользователь может обновить только field2
, это будет что-то вроде:
allow update: if request.resource.data.keys().hasAll(['field1', 'field2', 'field2']) &&
isUnmodified('field1')) && isUnmodified('field3'));