В вашем вопросе есть несколько аспектов, на которые необходимо ответить:
1 / На каком уровне следует писать правила безопасности?
Если вы пишете только на* Уровень 1007 *, как показано ниже, вы не сможете запросить весь набор задач.
Вы можете проверить его, выполнив следующие действия:
Правила:
{
"rules": {
"tasks": {
"$taskID": {
".read": "auth != null",
".write": "auth != null"
}
}
}
}
JS:
var db = firebase.database();
var ref = db.ref('tasks');
firebase.auth().signInWithEmailAndPassword("....", "....")
.then(function(userCredential) {
ref.once('value').then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
console.log(childSnapshot.val());
});
});
});
Это не будет выполнено с сообщением «Ошибка: access_denied at / tasks: у клиента нет прав доступа к нужным данным.»
При изменении var ref = db.ref('tasks');
var ref = db.ref('tasks/123456');
(123456 - существующий идентификатор задачи), вы получите результат.
Если вы измените свои правила на следующие, два предыдущих запроса будут работать.
{
"rules": {
"tasks": {
".read": "auth != null",
".write": "auth != null"
}
}
}
2 / Как сделать, чтобы получить только те задачи, в которых поле идентификатора пользователя имеет вид auth.uid?
Первое, на что следует обратить внимание, это то, что «Правила не являются фильтрами», как подробно описано здесь.: https://firebase.google.com/docs/database/security/securing-data#rules_are_not_filters
Так что если вы реализуете правила безопасности следующим образом:
{
"rules": {
"tasks": {
"$taskId": {
".read": "auth != null && data.child('user').val() === auth.uid",
".write": "auth != null"
}
}
}
}
Вам нужно будет написать квУбедитесь, что включает такое же ограничение для пользовательского идентификатора пользователя, как показано ниже:
var db = firebase.database();
firebase.auth().signInWithEmailAndPassword("....", "....")
.then(function(userCredential) {
var ref = db.ref('tasks').orderByChild('user').equalTo(userCredential.user.uid);
ref.once('value').then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
console.log(childSnapshot.val());
});
});
});
Но этот запрос не будет работать , опять-таки, потому что "Ошибка: license_deniedat / tasks: Клиент не имеет разрешения на доступ к нужным данным. "
Вы также не можете выполнить следующее, так как" Более мелкие правила безопасности переопределяют правила на более глубоких путях. ":
{
"rules": {
"tasks": {
".read": "auth != null",
".write": "auth != null"
"$taskId": {
".read": "auth != null && data.child('user').val() === auth.uid",
".write": "auth != null"
}
}
}
}
Одним из решений является использование правил на основе запросов (см. Документ здесь ) и запись ваших правил следующим образом:
{
"rules": {
"tasks": {
".read": "auth != null &&
query.orderByChild == 'user' &&
query.equalTo == auth.uid",
".write": "auth != null"
}
}
}
Однако, как вы, вероятно, заметили,это не позволит вам упорядочить ваш запрос (и отфильтровать его) по чему-то другому, чем user
(например, status
), поскольку «Вы можете использовать только один метод order-by за раз».
Поэтому решение будет состоять в том, чтобы создать вторую структуру данных параллельно существующей структуре, где вы добавите пользователя в качестве верхнего узла, например
"tasks"
"$taskId"
...
"user": "firebase user id"
"tasksByUser"
"$userId"
"$taskId"
...
. Вы будете использовать метод update () для записи вдве структуры данных одновременно.Смотри документ здесь .