Правила безопасности Firebase: получение документа с пробелом в documentId

#firebase #google-cloud-firestore #firebase-security

#firebase #google-cloud-firestore #firebase-безопасность

Вопрос:

Я пишу правила безопасности firebase и пытаюсь получить документ, в идентификаторе документа которого может быть пробел.

У меня есть следующий фрагмент, который хорошо работает, когда в документе нет пробела

     function isAdminOfCompany(companyName) {
        let company = get(/databases/$(database)/documents/Companies/$(companyName));
        return company.data.authorizedUsers[request.auth.uid].access == "ADMIN;
    }
 

В коллекции «Компании» у меня есть документ под названием «Тест», а другой называется «Тестовая компания» — попытка получить документ, соответствующий «Тест», работает нормально, но «Тестовая компания», похоже, не работает, поскольку переменная company (первая строка в функции)равно null в соответствии с правилами безопасности firebase «игровая площадка».

Я думаю, что это как-то связано с кодировкой URL, но замена пробела в documentId на » » или » » не меняет результат. Возможно, пробелы являются недопустимыми символами для идентификаторов документов (https://cloud.google.com/firestore/docs/best-practices перечисляет несколько лучших практик)

Любая помощь будет оценена!

РЕДАКТИРОВАТЬ: Согласно нескольким комментариям, я добавлю несколько дополнительных изображений / пояснений ниже.

Вот структура моей базы данных
введите описание изображения здесь

А вот какие поля присутствуют в пользовательских документах
введите описание изображения здесь

Короче говоря, следующий фрагмент воспроизводит проблему (я на самом деле не использую это, но он демонстрирует проблему таким же образом)

 rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
      
    match /Users/{user} {
      allow update: if findPermission(resource.data.company) == "MASTER" 
    }
        
    function findPermission(companyName) {
      let c = get(path("/databases/"   database   "/documents/Companies/"   companyName));
      return c.data.authorizedUsers[request.auth.uid].access;
    }        
  
  }
}
 

Когда я пытаюсь обновить пользователя, вызываемого test@email.com (который принадлежит компании «Test»), операция разрешена, и все работает точно так, как ожидалось.

Проблема возникает, когда пользователь, вызванный test2@email.com , который принадлежит компании «Test Company», приходит и делает тот же запрос (с авторизацией email / uid, обновленным в playground, чтобы соответствовать тому, что фактически найдено в структуре компании), запрос завершается неудачей. Запрос завершается с ошибкой, поскольку вызов get() (строка 1 функции) не может найти документ компании, соответствующий «Тестовой компании», на что указывает переменная «c», равная нулю на скриншоте (см. Ниже) — ОНА НЕ РАВНА НУЛЮ ПРИ ПОИСКЕ «Test»

Ниже приведен скриншот сообщения об ошибке, а также некоторые из соответствующих переменных при возникновении ошибки

введите описание изображения здесь

Комментарии:

1. Я бы настроил вашу систему так, чтобы документ не мог быть создан с пробелом, и написал функцию для замены его на в любом случае, когда будет использоваться пробел. Это предотвратит проблемы в будущем и поможет с хранением.

2. Спасибо за быстрый ответ! Я попытался заменить пробелы на как таковой «»» CompanyName.replace(» «, » «) «»» и все равно безуспешно. Я даже проверил, что путь, по которому выполнялся этот запрос, совпадает с простым доступом непосредственно к этому документу. Пути точно совпадают, но вызов get по-прежнему завершается ошибкой. Как прямой запрос get, так и запрос get через эту функцию, оба вызывают путь «/databases/(default)/documents/Companies / Test Company», но это работает только в том случае, если я делаю вызов get напрямую

3. firebaser здесь я не уверен, что правильно понимаю: вы говорите, что get(/databases/$(database)/documents/Companies/$(companyName) не удается прочитать документ $(companyName) , содержащий пробел? Для меня это звучит как ошибка, поэтому вы можете: 1) подтвердить мое понимание, 2) показать больше воспроизведения с кодом, ошибками и скриншотами документа (чтобы нам было легче воспроизвести проблему).

4. Привет, Фрэнк, это совершенно верно. Если переменная CompanyName содержит пробел, запрос завершается ошибкой. Точно такой же код (который аутентификация и т. Д. Изменены соответствующим образом) Работает, когда в идентификаторе документа нет пробела. Я отредактировал свой первоначальный вопрос и включил дополнительные сведения, изображения и пояснения. Пожалуйста, дайте мне знать, если потребуется какое-либо дополнительное разъяснение!

Ответ №1:

Проверьте, какой тип space на всякий случай, если это другой непечатаемый символ. Вы можете преобразовать его в Юникод и проверить, что это может быть. Однако использование пробелов при именовании переменных и структур данных считается плохой практикой. Существует так много разных типов, которые следует учитывать.

     | Unicode | HTML   | Description        | Example | 
    |---------|--------|--------------------|---------| 
    | U 0020  | amp;#32   | Space              | [ ]     | 
    | U 00A0  | amp;#160  | No-Break Space     | [ ]     | 
    | U 2000  | amp;#8192 | En Quad            | [ ]     | 
    | U 2001  | amp;#8193 | Em Quad            | [ ]    | 
    | U 2002  | amp;#8194 | En Space           | [ ]     | 
    | U 2003  | amp;#8195 | Em Space           | [ ]    | 
    | U 2004  | amp;#8196 | Three-Per-Em Space | [ ]     | 
    | U 2005  | amp;#8197 | Four-Per-Em Space  | [ ]      | 
    | U 2006  | amp;#8198 | Six-Per-Em Space   | [ ]      | 
    | U 2007  | amp;#8199 | Figure Space       | [ ]     | 
    | U 2008  | amp;#8200 | Punctuation Space  | [ ]     |
    | U 2009  | amp;#8201 | Thin Space         | [ ]      |
    | U 200A  | amp;#8202 | Hair Space         | [ ]      |