#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 | [ ] |