Правила пожарного магазина | Разрешить получение документов, только если указаны идентификаторы документов

Я получаю свои документы на основе списка идентификаторов.

db.collection("fruits").where(db.FieldPath.documentId(), "in", fruitIds).get()

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

db.collection("fruits").get()
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
37
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это невозможно именно так, как вы требуете. Что вы можете сделать, так это установить свои правила следующим образом:

match /fruits/{id} {
  allow get: true;
  allow list: false;
}

Это позволяет клиентам получить документ, если им известен идентификатор, но делает невозможным массовый запрос документов.

Затем вам нужно будет закодировать запрос клиентского приложения для каждого документа отдельно с помощью DocumentReference get() (вместо запроса с предложением where). Снижение производительности при этом незначительно (нет, нет никакого заметного прироста производительности при использовании запроса "in" так, как вы здесь показываете, и в любом случае вы ограничены 10 документами в пакете).

Это хорошее решение, но не могли бы они также сделать allow read: if request.data.id != null ?

sleepystar96 21.03.2022 01:00

@sleepystar96 Нет, это не сработает. request.data нет. См. определение Объект запроса. Кроме того, нет никакого способа сделать то, что вы предлагаете.

Doug Stevenson 21.03.2022 03:15

А, ты прав, спасибо @Doug

sleepystar96 21.03.2022 03:18

Поскольку @Дуг описан в их ответ, в настоящее время он не поддерживается должным образом.

Однако, глядя на Справка, вы можете, по крайней мере, ограничить операции list (запрос), наложив условия на orderBy и limit, используемые любыми запросами, чтобы усложнить их, а не полностью блокировать.

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

Это будет означать изменение вашего запроса на:

db.collection("fruits")
  .where(db.FieldPath.documentId(), "in", fruitIds)
  .orderBy(db.FieldPath.documentId()) // probably implicitly added by the where() above, but put here for good measure
  .limit(10) // this limit applies to `in` operations anyway, but for this to work needs to be added
  .get()
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /fruits/{fruit} {
      allow read: if <condition>
      // Limit documents per request to 10 and only if they provide an orderBy clause
      allow list: if <condition>
                  && request.query.limit <= 10
                  && request.query.orderBy = "__name asc" // __name is FieldPath.documentId()
      allow write: if <condition>;
    }
  }
}

Используя эти ограничения, это больше не должно работать:

db.collection("fruits").get()

Но вы все равно можете очистить все более мелкими фрагментами, используя:

const fruits = [];
const baseQuery = db.collection("fruits")
    .orderBy(db.FieldPath.documentId())
    .limit(10);

while (true) {
  const snapshot = await (fruits.length > 0
    ? baseQuery.startAt(fruits[fruits.length-1]).get()
    : baseQuery.get())

  Array.prototype.push.apply(fruits, snapshot.docs);
  
  if (snapshot.empty) {
    break;
  }
}

// here, fruits now contains all snapshots in the collection

Другие вопросы по теме