# #firebase #google-cloud-firestore #firebase-security
Вопрос:
Как использовать общую функцию ниже для вложенных полей? У меня есть этот документ ниже, который живет по адресу /userdata/{uid}
:
Как видно userBirthTime
, это карта, она содержит другую карту, birthTime
которая, в свою очередь, содержит поля, которые я хочу уточнить для их типов, например, проверьте, соответствует ли входящий year
тип int
, прежде чем его можно будет хранить в firestore.
Как бы я это сделал? Возможно ли это вообще для вложенных полей? Я пытался с
function isInteger(fieldName) { return request.resource.data[fieldName] is int }
а потом использовал его вот так
isInteger('userBirthTime.birthTime.year')
с общим правилом безопасности, которое заключается в следующем
match /userdata/{uid} {
allow write: if isInteger('userBirthTime.birthTime.year')
}
но это просто всегда возвращается true
, даже если я попытаюсь использовать string
as fieldName
, а не требуемый int
тип?!
Что я делаю не так? Дело в том, что это вложенное поле, а не поле верхнего уровня?
Ответ №1:
Очевидно, точечная нотация не работает в правилах безопасности (хотя она всегда возвращает значение false).:
// the request body
"data": {
"userBirthTime": {
"birthTime": {
"year": "string"
}
}
}
Изменение правил на это работает для меня:
function isInteger(fieldName) {
return request.resource.data.userBirthTime.birthTime[fieldName] is int
}
match /userdata/{uid} {
allow write: if isInteger('year'); // other fields
}
Комментарии:
1. Я вижу… Хм… ладно, основным недостатком этого, конечно, тогда я не могу иметь одну универсальную функцию больше, что работает для других полей в других карт, а также, но я буквально приходится жестко кодировать «путь» вплоть до каждого вложенного поля 🤔 например, я могу использовать
isInteger()
, чтобы проверить количество собак, а также и так далее:isInteger('userPets.numberDogs')
2. @Tom да, но с другой стороны, может быть, вы можете написать функцию для проверки всех детей на время рождения и так далее, возможно, для домашних животных.
3. Я обновил скриншот выше, чтобы показать больше карт в корне этого документа. Чтобы прояснить рассматриваемую тему: моя цель состоит в том, чтобы иметь одну универсальную функцию, которая проверяет наличие типов, таких как
int
илиstring
, которые работают для различных полей внутри этого документа, которые находятся на разных глубинах и в разных местах внутри этого документа. Например:isInteger('userBirthTime.birthTime.year')
но такжеisInteger('userBirthTime.eventDetail.startValue')
. Вот в чем сложность, как мне это сделать с помощью одной общей функции? 🤓4. @Tom Я имею в виду, что вам придется передать значение самостоятельно, например:
isInteger(request.resource.data.userBirthtime.birthTime.year)
теперь isInteger можно использовать где угодно или что-то подобное. Вы можете передать несколько аргументов в функции, чтобы передать объект запроса и выполнить некоторую обработку.