Query Firestore документы с защитой на основе ролей через Flutter - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть модель данных на основе ролей в Firestore согласно предложению googles: https://firebase.google.com/docs/firestore/solutions/role-based-access

Правила безопасности установлены правильно и работают нормально.Но теперь у меня проблема с тем, как запросить роли.

Это моя модель данных (один образец документа):

id: "1234-5678-91234",
roles:
    userId_1:"owner",
    userId_2:"editor
title: "This is a sample document"

И этоmy Firestore Query во Flutter, который получает все документы для конкретного пользователя по его идентификатору, если пользователь назначил роль "владелец" для документа:

return firestore
.collection(path)
.where("roles.${user.firebaseUserId}", isEqualTo: "owner")
.snapshots().map((snapshot) {
  return snapshot.documents.map((catalog) {
    return SomeDocumentObject(...);
  }).toList();
});

Моя проблема сейчас в том, что мне нужно какое-то предложение "ИЛИ", которого, насколько я знаю, не существует. Приведенный выше запрос извлекает документы только для пользователей с ролью "владелец" , ноМне нужен запрос, который также извлекает документ, если userId связан с ролью «редактор».

Я пробовал «arrayContains:», что также, похоже, не работает (потому что этоs map).

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

Возможно, у кого-то из вас есть подсказка длямне?:)

Спасибо и всего наилучшего, Майкл

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Это окончательное решение с использованием RxDart , Observables и .combineLatest () - возможно, это поможет кому-то там:

@override
Stream<List<Catalog>> catalogs(User user) {

    // Retrieve all catalogs where user is owner
    Observable<QuerySnapshot> ownerCatalogs = Observable(firestore
        .collection(path)
        .where("roles.${user.firebaseUserId}", isEqualTo: "owner")
        .snapshots());

    // Retrieve all catalogs where user is editor
    Observable<QuerySnapshot> editorCatalogs = Observable(firestore
        .collection(path)
        .where("roles.${user.firebaseUserId}", isEqualTo: "editor")
        .snapshots());

    // Convert merged stream to list of catalogs
    return Observable.combineLatest([ownerCatalogs, editorCatalogs],
        (List<QuerySnapshot> snapshotList) {
      List<Catalog> catalogs = [];

      snapshotList.forEach((snapshot) {
        snapshot.documents.forEach((DocumentSnapshot catalog) {
          catalogs.add(Catalog(
            id: catalog.documentID,
            title: catalog.data['title'],
            roles: catalog.data['roles'],
          ));
        });
      });
      return catalogs;
    }).asBroadcastStream();
  }
0 голосов
/ 31 декабря 2018

Firestore в настоящее время не имеет логических операций ИЛИ.Вам нужно будет выполнить два запроса, по одному для каждого условия, и объединить результаты обоих запросов в клиентском приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...