правила безопасности firestore / тип поля проверки во вложенном объекте

# #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 можно использовать где угодно или что-то подобное. Вы можете передать несколько аргументов в функции, чтобы передать объект запроса и выполнить некоторую обработку.