Правила Firebase: ограничение чтения для динамических дочерних узлов - PullRequest
0 голосов
/ 26 августа 2018

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

У меня есть следующая модель данных:

/groupMessages/<groupId>/<messageId>/

{
    "senderId": "<senderId>",
    "recipientId": "<recipientId>",
    "body": "..."
}

groupId, messageId, senderId и receientId являются динамическими идентификаторами.Я хотел бы присоединить слушателя к узлу / groudId для прослушивания новых сообщений.В то же время я хочу, чтобы пользователи только читали сообщение, в котором senderId или receientId соответствует соответствующему значению auth.token.

Из-за правил каскадирования Firebase, если я разрешу чтение на уровне groupId без ограничений, яне могу отрицать их на уровне сообщения.

{
    "rules": {
        "groupMessages"
           "$groupId": {
            ".read": "auth != null"
           }
        }   
    }
}

Я также не нашел способа ограничить правило чтения на уровне groupId для проверки отправителя / получателя сообщения.

Любые предложения с благодарностью.

1 Ответ

0 голосов
/ 26 августа 2018

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

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

var query = ref.child("groupMessages").child(groupId).orderByChild("senderId").equalTo(uid);

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

{
  "rules": {
    "groupMessages": {
      "$groupId": {
        ".read": "auth.uid != null &&
            query.orderByChild == 'senderId' &&
            query.equalTo == auth.uid"
      }
    }
  }
}

Запрос и правила теперь точно совпадают, поэтому правила безопасности разрешат запрос, в то время как они отклонят более широкую операцию чтения.,Подробнее об этом см. правила на основе запросов в документации Firebase

. Обратите внимание, что это работает только для одного поля.Запросы к базе данных Firebase могут фильтроваться только по одному полю.Хотя существуют обходные пути, объединяющие несколько значений в одно свойство , я не думаю, что они применимы к вашему сценарию, поскольку они работают только для запросов AND, где, как вам кажется, требуется OR.

Вы также, кажется, хотите запросить /groupMessages вместо сообщений для определенной группы.Это также невозможно: база данных Firebase упорядочивает / фильтрует свойство по фиксированному пути под каждым дочерним узлом узла, в котором выполняется запрос.Вы не можете выполнять запросы на двух динамических уровнях, как вы, кажется, пытаетесь.Подробнее об этом см .: Запрос Firebase с двойным вложением и Запрос Firebase, если child of child содержит значение .

Распространенным решением вашей проблемы является создание спискаидентификаторов для каждого пользователя, который содержит только идентификаторы всех сообщений (и / или групп), к которым он имеет доступ.

userGroups: {
  uid1: {
    groupId1: true,
    groupId2: true
  },
  uid2: {
    groupId2: true,
    groupId3: true
  }
}

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

Наконец: этот тип рекурсивной загрузки не так неэффективен, как думают многие разработчики, поскольку Firebase направляет запросы по существующему соединению.

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