Правила безопасности Firestore: не удается проверить, соответствует ли документ из вложенной коллекции пользовательскому UID - PullRequest
2 голосов
/ 25 апреля 2019

Проблема

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

Каждый пользователь может голосовать только один раз за каждую идею, и система должна быть безопасной (вы не можете удалить голос другого человека или создать голос, как если бы вы были другим человеком)

Как я могу проверитьесли пользователь уже проголосовал через правила безопасности?В этом нет необходимости, но я бы предпочел не использовать get () и вместо этого использовать идентификатор документа в качестве идентификатора.

Что я пробовал

Внутри правил безопасности Firestore я сделалпростая проверка для пользователей для создания правильных идей.

Затем я разрешаю им создавать документы голосования в подколлекции (idea_likes), я попытался проверить, соответствует ли подстановочный знак документа голосования идентификатору пользователя, но безуспешно, но мне удалосьпроверьте, совпадает ли поле ID пользователя с auth.userid, хотя это усложняет чуть-чуть битное кодирование клиента, чтобы показать, проголосовал ли пользователь или нет.

Как я пытался

Вот какЯ разрешаю кому-то создавать идеи:

     match /ideas/{document} {
       // Anyone signed in can create ideas 
       allow create: if isSignedIn()
       // Idea creation data validation
         && documentRequestNewData().idea is string
         && documentRequestNewData().title is string
         && documentRequestNewData().owner is string
         && documentRequestNewData().votes is number
         && documentRequestNewData().date is timestamp;
     }

И вот прямо под ними я попытался разрешить кому-то создавать голоса:

match /ideas/{document}/idea_likes/{likeId} {
       allow create, delete: if isSignedIn()
         && request.resource.data.owner == request.auth.uid
         && request.auth.uid == likeId;
     }

Я также пытался разделитьподстановочный знак {likeId}:

match /ideas/{document}/idea_likes/{likeId} {
       allow create, delete: if isSignedIn()
         && request.resource.data.owner == request.auth.uid
         && likeId.split('/')[2] == request.auth.uid;;
     }

Проверка только для полей документа работает, но не помогает предотвратить дублирование голосов:

match /ideas/{document}/idea_likes/{likeId} {
       allow create: if isSignedIn()
         && request.resource.data.owner == request.auth.uid;
     }

Есть идеи?

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

Однако, как показано с использованием подстановочного знака и проверки, равен ли он запросу.auth.uid не работает.

Заранее благодарен за любую помощь

1 Ответ

0 голосов
/ 25 апреля 2019

В правилах безопасности вы не можете проверить, есть ли документ с определенным значением в коллекции, так как это означает, что правила должны читать все документы в коллекции, что делает их чрезмерно медленными / дорогими / не масштабируемыми ,

Однако вы можете проверить, существует ли документ с определенным идентификатором. Поэтому, если документы названы в честь UID голосования, вы можете проверить, голосовал ли уже пользователь.

Чтобы проверить, существует ли уже документ, используйте функцию exists, как показано здесь: https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents.

...