Разрешить первое создание данных в Firebase, а затем ограничить доступ


Я ищу решение, которое позволит впервые создать данные в Firebase, а затем впоследствии ограничить доступ к владельцу этих данных (или администратору). По сути, я создал процесс регистрации для бизнеса, который создает как пользователя в Firebase, так и связанного пользователя для этого бизнеса. К сожалению, с моей текущей схемой и правилами безопасности, я получаю ошибки permission_denied. Вот моя текущая схема, которая была сгенерирована EmberFire с помощью hasmany belongsTo связь между моделью business и моделью employee:

+ businesses
  + business_id (generated by EmberFire)
    - name
    + employees
      - employee_id
      - employee_id
+ employees
  + employee_id (generated by Firebase's auth system)
    - first name
    - last name
    - business_id
    - role (ex: 99 for admin)

И вот мои правила безопасности:

{
  "rules": {
    "businesses": {
      // allows only administrators of the business to read and write business data
      "$business_id": {
        ".read": "root.child('employees/' + auth.uid + '/business').val() === $business_id && root.child('employees/' + auth.uid + '/role').val() === 99",
        ".write": "root.child('employees/' + auth.uid + '/business').val() === $business_id && root.child('employees/' + auth.uid + '/role').val() === 99"
      }
    },
    "employees": {
      // only allow employees to read/write their own data or the admin of the business they belong to
      "$employee_id": {
        ".read": "auth.uid === $employee_id || (root.child('employees/' + auth.uid + '/role').val() === 99 && root.child('businesses/' + (root.child('employees/' + auth.uid + '/business').val()) + '/employees/' + $employee_id).exists())",
        ".write": "auth.uid === $employee_id || (root.child('employees/' + auth.uid + '/role').val() === 99 && root.child('businesses/' + (root.child('employees/' + auth.uid + '/business').val()) + '/employees/' + $employee_id).exists())"
      }
    }
  }
}

Может ли кто-нибудь рекомендовать обновленный набор правил безопасности/схемы, которые позволили бы изначально создавать данные во время регистрации, а затем впоследствии быть доступными только владельцу/администратору этих данных?

Примечание: В настоящее время я использую Firebase 2.2.4 и EmberFire 1.4.4.

Заранее спасибо, Джеймс

Обновить

Вот код используется в процессе регистрации:

// first, create the user account to be the admin of the business
_this.firebase.createUser({
  email: _this.get('email'),
  password: _this.get('password')
}, function(error, userData) {

  if (error) {
    flashMessages.warning(error);
  } else {

    // authenticate the user and log them in
    _this.get('session').authenticate('authenticator:firebase', {
      'email': _this.get('email'),
      'password': _this.get('password')
    }).then(function() {

      // create the business record
      var business = _this.store.createRecord('business', {
        name: _this.get('businessName')
      });

      // create the employee record and associate the firebase uid
      var employee = _this.store.createRecord('employee', {
        id: userData.uid,
        firstName: _this.get('firstName'),
        lastName: _this.get('lastName'),
      });

      // add the employee<->business relationship
      business.get('employees').then(function(employees) {
        employees.addObject(employee);
      });

      // save the records to Firebase
      employee.save().then(function() {
        business.save();
      });

    }).catch(function(error) {
      flashMessages.warning(error);
    });

  }

}); 

Кроме того, вот снимок данных, иллюстрирующий то, что я описал:

Моментальный Снимок Данных

1 2

1 ответ:

Ваше правило безопасности требует role = 99, но вы никогда не устанавливаете его.

Следующее, кажется, решает вашу проблему:

// create the employee record and associate the firebase uid
var employee = _this.store.createRecord('employee', {
  id: userData.uid,
  firstName: _this.get('firstName'),
  lastName: _this.get('lastName'),
  role: 99
});

Чтобы ответить на более важный вопрос, да, запись выполняется в нескольких частях. Отношения hasMany сохраняются индивидуально, чтобы не полностью перезаписывать любые изменения, которые могут происходить на других клиентах. Более конкретно, каждая ссылка hasMany добавляется или удаляется в отдельной записи, поэтому может быть 2или более записей.

В случае ваш код, ссылка business/<id>/employees<employee_id> была сохранена первой, что означало, что на втором проходе - при написании основного хэша business/<id> - часть вашего правила не удалась. Это нормально, потому что сотрудник создан и связан с бизнесом, но проверка role = 99 также не удалась.