Правила безопасности Firestore, основанные на значениях карты
Я хочу сохранить, разрешено ли пользователю читать документ в самом документе, основываясь на адресе электронной почты пользователя. Несколько пользователей должны иметь доступ к одному и тому же документу.
Согласно документации Firestore не позволяет запрашивать элементы массива. Вот почему я храню адреса электронной почты пользователей в карте String-Bool с адресом электронной почты в качестве ключа.
В следующем примере я не использую электронные письма в качестве ключей карты, потому что он уже не работает с основные строки.
Структура базы данных выглядит следующим образом:
lists
list_1
id: String
name: String
owner: E-Mail
type: String
shared:
test: true
Здесь перечислены все правила безопасности:
service cloud.firestore {
match /databases/{database}/documents {
match /lists/{listId=**} {
allow read: if resource.data.shared.test == true
}
}
}
Edit: он также не работает, если я использую match /lists/{listId}
вместо match /lists/{listId=**}
shared[test]
верно.
Для полноты: это запрос, который я использую (Kotlin на Android):
collection.whereEqualTo("shared.test", true).get()
.addOnCompleteListener(activity, { task ->
if (task.isSuccessful) {
Log.i("FIRESTORE", "Query was successful")
} else {
Log.e("FIRESTORE", "Failed to query existing from Firestore. Error ${task.exception}")
}
})
Я предполагаю, что не могу получить доступ к значениям карт из правил безопасности. Так каким же будет альтернативное решение моей проблемы?
В справочнике правил Firestore написано, что карты могут быть доступны таким образом resource.data.property == 'property'
Итак, что я делаю не так?
2 ответа:
Edit: эта проблема должна быть исправлена сейчас. Если вы все еще видите его (и уверены, что это ошибка с оценщиком правил), дайте мне знать в комментариях.
Я поговорил с некоторыми людьми здесь о проблеме, с которой вы столкнулись, и, похоже, это проблема с самими правилами безопасности. По существу, проблема, похоже, специфична для оценки вложенных полей в запросах, как то, что вы делаете.
Итак, в принципе, то, что вы делаете, должно работать нормально, и вам нужно будет дождитесь обновления от команды Firestore, чтобы выполнить этот запрос. Я постараюсь не забыть обновить этот ответ, когда это произойдет. Прости меня за это!
Всякий раз, когда у вас есть (необязательно) вложенные свойства, Вы должны убедиться, что свойство существует, прежде чем продолжать проверять его значение, например.
allow read: if role in request.auth.token && request.auth.token[role] == true
В вашем случае:
allow read: if test in resource.data.shared && resource.data.shared.test == true
, я долго боролся с ролями, пока не понял, что у пользователей, не являющихся администраторами, поле администратора не определено, и правила firestore просто вылетают и не продолжают проверять другие возможные совпадения.
Для пользователя без токена.администратор, это всегда будет сбой независимо от того, если у вас есть другие совпадения, которые являются истинными, например:
function userHasRole(role) { return isSignedIn() && request.auth.token[role] == true }