Cloud Firestore Security Rules - разрешить запись только в определенный ключ в документе - PullRequest
2 голосов
/ 20 июня 2019

В настоящее время я пишу некоторые правила для моего приложения с базой данных Firestore. В настоящее время каждый может читать данные, а авторизованные пользователи могут писать.

  match /quizzes/{quizId} {
    allow read; 
    allow write: if request.auth != null;
  }

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

Пример содержимого документа:

{
  title: 'title',
  plays: 12,
  playedBy: [//Filled with user id's],
  ...
}

Есть ли способ, который ограничивает не прошедших проверку подлинности пользователей только доступом на запись к массиву PlayBy, а не к другим ключам этого документа?

1 Ответ

3 голосов
/ 20 июня 2019

Конечно.Но это может стать немного сложным, если у вас много полей.

Давайте начнем с самого простого примера.Примерно так позволяет неаутентифицированному пользователю писать playedBy, если это единственное поле в документе:

if request.auth != null || request.resource.data.keys().hasOnly(['playedBy'])

Это работает, если неаутентифицированный пользователь создает новый документ или обновляет существующийодин.Но он остановится, как только в документе появятся другие поля, так как request.resource.data содержит все поля, которые будут у документа после успешного завершения записи.

Поэтому лучшей альтернативой является проверка того, что изменен только playedByи что все остальные поля имеют то же значение, что и раньше.Сложный момент - обработка несуществования полей, которые я обычно обрабатываю с помощью нескольких вспомогательных функций:

function isUnmodified(key) {
  return request.resource.data[key] == resource.data[key]
}
function isNotExisting(key) {
  return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
}

А затем:

if request.auth != null &&
  request.resource.data.keys().hasOnly(['title', 'plays', 'playedBy']) &&
  isUnmodified('title') && 
  isUnmodified('plays')

Точное правило может бытьнемного, но я надеюсь, что этого достаточно, чтобы вы могли завершить это самостоятельно.

...