Как написать правило Firestore, чтобы оно соответствовало полю электронной почты в документе

# #google-cloud-firestore #firebase-security

Вопрос:

У меня есть поле с пометкой «электронная почта» в моих документах «MyCollection», и я пытаюсь написать правило firestore, разрешающее удаление, когда запись электронной почты зарегистрированного пользователя совпадает с электронной почтой в записи. Я закодировал свое правило следующим образом:

 match /myCollection/{email} {  allow delete : if request.auth != null amp;amp; request.auth.token.email == email; }  

Это не позволяет удалить соответствующие записи. Совет был бы признателен, потому что, хотя этот вопрос задавался много раз в StackOverflow, ответы, которые я видел, противоречивы, и ни один из них не работает для меня.

Я тестирую это на «игровой площадке», и если я установлю «местоположение» в MyCollection/{documents=**}, правило не сработает. Смотрите скриншоты ниже:

Детская площадка (сверху) Детская площадка (внизу)

Код удаления в моей программе гласит:

 const myCollectionCol = collection(db, 'myCollection');  const myCollectionQuery = query(myCollectionCol, where("email", "==", email));  const myCollectionSnapshot = await getDocs(myCollectionQuery);  myCollectionSnapshot.forEach((doc) =gt; {  deleteDoc(doc.ref);  });  

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

1. «Это не позволяет удалить соответствующие записи». Насколько я вижу, правило должно разрешать удаление. Можете ли вы показать, как вы это проверяете?

2. @FVP : Спасибо, что поднял это, Фрэнк. Я пытаюсь двумя способами, во-первых, в своей программе, а во-вторых, на «игровой площадке». Придерживаясь последнего, я установил «Тип моделирования» в «удалить», а местоположение в » /MyCollection/{document=**}». Затем я включил аутентификацию и установил для»электронной почты» значение, существующее в «Коллекции». Когда я нажимаю «запустить», он отскакивает от меня. Удалите часть правилаamp;amp;, и я очищен.

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

4. @FVP : Я отредактировал исходный вопрос в соответствии с просьбой. Я обнаружил, что если я изменю расположение игровой площадки на myCollection/samuil.johnson@yahoo.com, где samuil.johnson@yahoo.com это адрес в коллекции MyCollection, по которому правило принимает удаление. Так в чем же проблема в моем коде?

Ответ №1:

Вы запускаете запрос, который возвращает все документы, в которых есть поле email со значением, равным переменной электронной почты:

 query(myCollectionCol, where("email", "==", email))  

Но ваши правила разрешают удалять только документ, у которого идентификатор документа *равен свойству электронной почты пользователя в маркере аутентификации.

Итак, чтобы удалить единственный документ, который вам разрешено удалить:

 import { getAuth } from "firebase/auth";  const auth = getAuth(); const user = auth.currentUser; const myEmailAddress = user.email;  ...  const myCollectionCol = collection(db, 'myCollection');  deleteDoc(doc(myCollectionCol, myEmailAddress));   

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

 match /myCollection/{doc} {  allow delete : if request.auth != null amp;amp;   request.auth.token.email == resource.data.email;  // 👆 the email field in the doc }  

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

1. Вау — это тонкость, которая прошла прямо над моей головой. Итак, могу ли я спросить, как бы я закодировал правило, позволяющее пользователю удалять /все/ документы, содержащие их адрес электронной почты?