#javascript #firebase #google-cloud-firestore #firebase-security
# #javascript #огневая база #google-cloud-firestore #firebase-безопасность
Вопрос:
у меня есть база данных firestore, и в ней есть некоторая коллекция. каждая коллекция содержит несколько документов, и в документе будет поле с именем userId. Этот идентификатор пользователя — это то, что я хочу сопоставить при написании правила безопасности. Мои данные выглядят следующим образом. посмотрите на коллекцию пользователей одного конкретного объекта.
Теперь я хочу, чтобы правило безопасности было примерно таким:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{User}{
allow read, write: if resource.data.userId == request.auth.uid;
}
}
}
когда я делаю вызов для чтения данных:
import firestore from '@react-native-firebase/firestore';
console.log(`made db call to update menu for userid ${user.uid}`);
try{
var querySnapshot = await firestore().collection('Users').get();
console.log(querySnapshot.size);
querySnapshot.forEach(documentSnapshot => {
console.log('snapshot ID: ', documentSnapshot.id, documentSnapshot.data());
});
вот ошибка, которую я получаю вместе с используемым зарегистрированным идентификатором пользователя:
[Пт, 11 декабря 2020 г., 15:53:22.649] Внесенный в журнал вызов базы данных для обновления меню для идентификатора пользователя CKKMUujnojNiUGO7z8FHxtnquQ53
[Пт, Дек. 11 2020 15:53:22.808] ЖУРНАЛ [Ошибка: [firestore / отказано в разрешении] У вызывающего абонента нет разрешения на выполнение указанной операции.]
я получаю эту ошибку: [Ошибка: [firestore/ permission-denied] У вызывающего абонента нет разрешения на выполнение указанной операции.] я в принципе не могу поставить какое-либо условие, которое зависит от resource.data. я жестко запрограммировал идентификатор один раз и поставил request.auth.uid ==»жестко запрограммированный идентификатор», и это тоже сработало. я думаю, что каким-то образом resource.data.userId не восстанавливается, хотя для меня это выглядит правильно.
Комментарии:
1. «когда я делаю вызов для чтения данных», пожалуйста, отредактируйте свой вопрос, чтобы включить этот код. Также убедитесь, что оно соответствует требованиям ваших правил безопасности. Например: зарегистрируйте UID прямо перед вызовом и включите этот код и его выходные данные в вопрос.
2. @FrankvanPuffelen внес изменения в соответствии с вашими предложениями. также, если вы продолжаете читать мой вопрос, я упомянул, что когда я жестко кодирую правило, произнося request.auth.uid == «идентификатор, который я знаю», он работает, что доказывает, что идентификатор передается из запроса правильно.
Ответ №1:
Важно понимать, что правила безопасности Firestore — это не фильтры. Обязательно прочитайте эту связанную документацию. Правила безопасности не будут фильтровать документы так, чтобы они соответствовали только тому, что разрешено читать пользователю.
Ваш запрос требует всех документов в Users:
firestore().collection('Users').get();
Однако ваши правила настаивают на том, что пользователь должен запрашивать документы только в том случае, если его UID указан в поле userId документа:
allow read, write: if resource.data.userId == request.auth.uid;
Вы можете привести свой запрос в соответствие с требованиями правил, добавив фильтр в поле userId:
firestore()
.collection('Users')
.where('userId', '==', user.uid)
.get();