Как вы обнаружили, правила безопасности не могут использоваться для фильтрации данных.Но они могут использоваться для ограничения запросов, которые могут быть выполнены к данным.
Например, вы можете запросить все сообщения, где текущий пользователь является отправителем:
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 направляет запросы по существующему соединению.