Сравнение массивов / наборов в Правилах безопасности Firestore

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

Вопрос:

В моем случае документ обрабатывается несколькими пользователями определенной группы. Документ содержит (помимо других записей) два соответствующих поля для:

  • ownerUID (Строковое значение — представляет идентификатор пользователя владельца документа)
  • members (Массив строк — представляет идентификаторы всех участников, которым разрешено работать с этим документом)

Я хочу убедиться (используя правила безопасности), что (кроме владельца документа) ни один участник не сможет удалить другого участника из members массива — кроме себя.

Чтобы оценить это, я попытался использовать функцию ниже в своем Firestore Security Rules

 function onlyOwnMemberUIDRemovableOrOwner(){
        return request.auth.uid == resource.data.ownerUID ||
               resource.data.members.toSet().difference(request.resource.data.members.toSet()) == request.auth.uid.toSet();
}
 

Первое утверждение довольно очевидно и отлично работает для других правил в моей настройке, позволяющих owners изменять документы без ограничений:

 request.auth.uid == resource.data.ownerUID 
 

Второе утверждение вызывает у меня проблемы. Идея состояла в том, чтобы оценить недостающие значения в members поле с помощью .difference() функции for sets и сравнить ее с set единственной, содержащей собственные UID . Только если отсутствующее UID является собственным UID , функция должна вернуться true . К сожалению , даже при попытке удалить собственное UID , заявление все равно вернется false .

 resource.data.members.toSet().difference(request.resource.data.members.toSet()) == request.auth.uid.toSet()
 

Вы можете сказать мне, что я здесь делал не так?
Знаете ли вы лучший подход к решению этой проблемы?
Большое вам спасибо за вашу поддержку.

Ответ №1:

Две проблемы с вашим кодом:

  1. toSet() работает list и не работает string
  2. Вы должны убедиться ownerUID , что это не изменено

Вот исправленное правило:

 function onlyOwnMemberUIDRemovableOrOwner(){
  return request.resource.data.ownerUID == resource.data.ownerUID
    amp;amp; (request.auth.uid == resource.data.ownerUID ||
      resource.data.members.toSet().difference(request.resource.data.members.toSet()) == [request.auth.uid].toSet());
}
 

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

1. Большое вам спасибо 🙂