Как написать правило чтения для Firebase Firestore отношение «многие ко многим» - PullRequest
0 голосов
/ 07 мая 2018

У меня есть следующая структура данных в Firebase Firestore, чтобы представить отношения многие ко многим между клиентами и пользователями:

Clients
  clientId1 {
    users (object): {
      userId1: true
      userId2: true
    }
  }
  clientId2 {
    users (object): {
      userId1: true
    }
  }

Я запрашиваю его на Android, используя следующий запрос:

  db.collection("clients").whereEqualTo("users."+uid, true);

Для userId2 запрос должен возвращать только clientId1.

Если я задаю правило (разрешить чтение: если истина;), когда я выполняю запрос, указанный выше, я получаю верных клиентов.

Я также хотел бы настроить правило базы данных, чтобы userId2 не мог видеть clientId2.

Я попробовал это правило, но я не получил никаких результатов:

match /clients/{clientId} {

  //Allow read if the user exists in the user collection for this client
  allow read: if users[request.auth.uid] == true;

}

Я тоже пробовал:

match /clients/{clientId} {

  //Allow read if the user exists in the user collection for this client
  allow read: if resource.data.users[request.auth.uid] == true;

}

Но ни одно из приведенных выше правил не возвращает клиентов.

Как мне написать правило?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Я собираюсь ответить на свой собственный вопрос, поскольку я просто делал что-то глупое.

Моя структура данных в порядке, и правильный синтаксис для моего правила такой:

match /clients/{clientId} {

  //Allow read if the user exists in the user collection for this client
  allow read: if resource.data.users[request.auth.uid] == true;

}

Учитывая это:

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

Этот запрос Android правильно реализует правильный фильтр для правила:

db.collection("clients").whereEqualTo("users."+uid, true);

Я еще не правильно внедрил свой адаптер. Я хотел посмотреть, смогу ли я сначала получить правильную структуру данных / правила / запрос. Я вызывал его от другого слушателя, который прослушивал всю коллекцию клиентов (что не соответствует правилу), и поэтому этот запрос не вызывался. Ранее, когда я установил правило (allow read: if true;), первоначальный слушатель выполнял мой запрос и возвращал правильные результаты. Это заставило меня поверить в то, что мое правило было неверным, когда его не было.

0 голосов
/ 07 мая 2018

Согласно официальной документации относительно правил безопасности Firestore :

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

Таким образом, вы не можете фильтровать документы, существующие в вашей базе данных, с использованием правил безопасности.

...