Правила безопасности Firebase Уровни множественного доступа Emberfire Per Node

У меня две модели Ember: a items и comments. Пользователь отправит элемент, а другие пользователи смогут прокомментировать элементы.

Я не могу настраивать правила безопасности в firebase, которые позволяют name и description записываться только текущим пользователем, но позволяют записывать comments любым зарегистрированным пользователем.

Item

// app/models/item.js
export default DS.Model.extend({
  name: DS.attr('string'),
  description: DS.attr('string'),
  comments: DS.hasMany('comment'),
  user: DS.belongsTo('user')
})

Комментарий

// app/models/comment.js
export default DS.Model.extend({
  user: DS.belongsTo('user')
  body: DS.attr('string'),
  timestamp: DS.attr('string'),
  item: DS.belongsTo('user')
})

Сохранение комментария

// app/components/comment-form.js
const comment = this.get('comment');
const item = this.get('item');
// service that tracks the currently logged in user
const currentUser = this.get('sessionManager.user');
comment.set('timestamp', new Date());
comment.set('user', currentUser);

// setup both sides of the relationship
item.get('comments').pushObject(comment);
comment.set('item', item');

// save both
return Ember.RSVP.Promise.all([item.save(), user.save()]);

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

"items": {
    ".read": "auth !== null",
    "$item_id": {
        // only the currently logged in user can write to this node
        ".write": "root.child('users/'+data.child('user').val()+'/uid').val() === auth.uid",
        // allow any user to write comments
        "comments": {
            ".write": "auth !== null"
        }
    }
},

В симуляторе firebase это работает. Как пользователь, которому принадлежит элемент, я могу написать /items/<item_id>/description. Как пользователь, который не владеет этим элементом, я могу написать /items/<item_id>/comments/, но не /items/<item_it>/description. Однако он не работает в Ember, используя Emberfire.

Моя рабочая теория заключается в том, что когда я добавляю новый комментарий к элементу, который я не "владею", я вызываю item.save(). Emberfire пытается записать в /items/<item_id>.

Как настроить параметры безопасности Firebase таким образом, чтобы только пользователь, которому принадлежит item, мог обновлять большинство своих свойств, но любой пользователь может добавить comment

Здесь находится симулятор правил firebase:

Попытка написать в /items/<item_id>/comments с пользователем, который не владеет этим элементом элемента, с данными

{
    "cde": "comment_id"
}

будет успешно писать с помощью приведенных выше правил.

Однако

Попытайтесь написать в /items/<item_id> с пользователем, который не владеет этим элементом элемента, с данными

{
    "comments": {
        "cde": "comment_id"
    }
}

не удается.

Ответ 1

Проблема заключается в том, что в правиле .write вы использовали data предопределенная переменная и data относится к:

A RuleDataSnapshot, представляющий данные, существовавшие до попытки операции.

Для новых элементов data.exists() будет false. Чтобы пользователи могли писать новые элементы, вы должны использовать newData, а не:

".write": "root.child('users/' + newData.child('user').val() + '/uid').val() === auth.uid"

И если вы хотите разрешить удаление элементов, вы должны проверить наличие newData и использовать data, если он не существует:

".write": "root.child('users/' + (newData.exists() ? newData.child('user').val() : data.child('user').val()) + '/uid').val() === auth.uid"