безопасность firestore, относящаяся к данным

#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();