Правила безопасности 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 12

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
}