Правило Firestore не применяется к коллекции - PullRequest
0 голосов
/ 03 августа 2020

У меня есть коллекция Routines, где документы с полем programId не должны быть доступны для чтения.

У меня есть это правило хранилища:

match /Routines/{routineId=**} {
    allow write: if false;
    allow read: if !('programId' in resource.data);
}

Когда я Если получить документ из этой коллекции, правила работают как положено, но когда я получаю всю коллекцию, я получаю все документы, даже те документы, которые имеют набор programId. Таким образом, похоже, что это правило не применяется к коллекции.

Я получаю такую ​​коллекцию:

const res = await firebase.firestore().collection("Routines").get();

1 Ответ

2 голосов
/ 03 августа 2020

Проблема в том, что Правила безопасности Firestore не являются фильтрами . Обязательно прочтите и поймите эту документацию, а также этот пост . Ваш запрос запрашивает все документов в коллекции Routines. Правила безопасности либо разрешат этот запрос для всех документов, либо полностью отклонят его. Они не предоставят подмножество тех документов, которые соответствуют некоторым критериям. Если правила безопасности не будут сканировать содержимое всех документов, чтобы проверить их значения - это не будет масштабироваться массово, как того требует Firestore.

К сожалению, здесь возникает вторая проблема, заключающаяся в том, что на самом деле нет способа сопоставить ваш запрос ваши правила. Firestore не позволяет фильтровать наличие поля в документах. Вы можете фильтровать только известные значения полей, которые действительно существуют. Это означает, что вам следует рассмотреть альтернативы моделированию данных. Возможно, вы хотите добавить логическое поле с именем hasProgramId и убедиться, что оно всегда имеет значение true или false, чтобы его можно было использовать как в правилах, так и в фильтрах запросов.

Итак ваш запрос может быть таким:

const res = await firebase.firestore()
    .collection("Routines")
    .where("hasProgramId", "==", true)
    .get();

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

match /Routines/{routineId=**} {
    allow write: if false;
    allow read: if resource.data.hasProgramId;
}
...