FireBase Multi Path обновление и правила для каждого пути

1

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

Сначала я пытался реализовать ограничение путем запроса events узла в events .write правило, ищут событие, которое уже имело USERID равный auth.uid. Но я не мог понять, как это сделать, поэтому я решил создать новый узел, hosts, как таблицу поиска. Он просто хранит любые пользовательские идентификаторы, которые в настоящее время размещают событие. Если пользователь пытается создать событие, и их userId уже существует в hosts, то это ошибка.

Правила:

{
  "rules":{
        "users":{
            "$uid":{
                ".read": "auth.uid == $uid",
              ".write": "auth.uid == $uid",
              ".validate": "newData.exists()"
          }
      },
      "hosts":{
            "$uid":{
                ".read": "true",
                //to be a host, you must be a user
              ".write": "auth.uid == $uid &&    root.child('users').hasChild(auth.uid) &&   !root.child('hosts').hasChild(auth.uid)",
              ".validate": "newData.exists()"
          }
      },
      "events":{
          "$uid":{
                ".read": "true",
                //to create an event, you must be a host
              ".write": "root.child('hosts').hasChild(auth.uid)",
              ".validate": "true"
          }
      }
  }
}

Javascript:

createEvent(form){
    var user = firebase.auth().currentUser
    var db = firebase.database();
    var newEventRef = db.ref('events').push();
    var newEvent = {}
    newEvent[uid] = form*/

    var update = {
        ['hosts/'+user.uid]: true
        update['events/'+newEventRef.key] = form
    };
    db.ref().update(update)
        .then((...args)=>{
            ...
        })
        .catch(err=>{
            ...
        })
},

Проблема с вызовом обновления заключается в том, что он всегда терпит неудачу. Я пытаюсь вставить в hosts и events одновременно. Но правило write events ожидает, что userId будет находиться на hosts до того, как он начнет запись, поэтому я догадываюсь, почему он терпит неудачу.

Должен ли я сделать 2 отдельных обновления? 1, чтобы вставить userId в hosts, а затем, если это удастся, другая вставка в events?

Теги:
firebase
firebase-security
firebase-realtime-database

1 ответ

1
Лучший ответ

В правилах безопасности есть три переменные, которые относятся к данным:

  • data - данные, которые существуют в местоположении правила до его обновления
  • newData - данные, как они есть в местоположении правила после его обновления
  • root - данные, которые существуют в корне базы данных до их обновления

Поэтому, когда вы ссылаетесь на root в своих правилах, вы получаете данные до обновления. Чтобы получить обновленные данные, вы должны обратиться к newData. Поскольку, к сожалению, нет newRoot, вам нужно будет перейти от newData до требуемого уровня, вызвав parent() несколько раз.

Пример:

  "events":{
      "$uid":{
            ".read": "true",
            //to create an event, you must be a host
          ".write": "newData.parent().parent().child('hosts').hasChild(auth.uid)",
          ".validate": "true"
      }
  }
  • 0
    Это сработало, спасибо Фрэнк.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню