Обновление базы данных Firebase удаляет дочерние данные

1

Я пишу приложение списка событий, оно имеет иерархию Event> Part> Step. После того, как я создал событие, я могу "войти" в это событие и посмотреть список "частей", которые содержат список "шагов".

Как я структурировал свою базу данных, так что у меня есть объект, отсортированный по идентификатору пользователя, чтобы отображать события и его данные, а затем, когда я нажимаю на это событие, я вхожу в него, теперь смотрю на объект parts. Объект частей выглядит примерно так:

parts:
    eventID1:
        partID1:
            startDateTime:value,
            endDateTime:value,
            title:value,
            ...
        partID2:
            startDateTime:value,
            endDateTime:value,
            title:value,
            ...
        etc.

Это хорошо работает, я вытягиваю все части на идентификатор события. Проблема связана с шагами. Когда я добавляю шаг к части, я помещаю ее в два места (используя update); один в таблице шагов и один в самой части, добавив новый ключ: значение для part

объект шагов выглядит следующим образом:

steps:
    eventID1:
        partID1:
            stepID1:
                title:value,
                startDateTime:value,
                etc.
            stepID2:
                title:value,
                startDateTime:value,
                etc.

И наконец (область проблем) объект детали обновляется, чтобы выглядеть так:

parts:
    eventID1:
        partID1:
            startDateTime:value,
            endDateTime:value,
            title:value,
            ...
            steps:
                stepID1:
                    title:value,
                    startDateTime:value,
                    etc.
                stepID2:
                    title:value,
                    startDateTime:value,
                    etc.
        partID2:
            startDateTime:value,
            endDateTime:value,
            title:value,
            ...
        etc.

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

Каждое event, part и step имеют одинаковую структуру, поэтому я объединил все это в одну функцию (используя ионный 3/угловой4)

  update(action, type, eid, pid, sid, title, location, startDateTime) {
    console.log("Firebase Database Receiving: ", action, type, eid, pid, sid, title, location, startDateTime);
    let key = (action === "add") ? this.ref.push().key : null;
    console.log(key);
    let update;
    let object = {
      startDateTime: startDateTime,
      startDateTimeEpoch:  moment(startDateTime).format("X"),
      endDateTime: startDateTime,
      endDateTimeEpoch:  moment(startDateTime).format("X"),
      title: title,
      type: type,
      roles: {
        [this.firebaseAuthentication.uid]: "admin",
      },
      location: {
        title: location,
        street: '',
        city: '',
        state: '',
        zip: '',
        timeZone: ''
      },
    };
    if(type === "events"){
      key = (key) ? key : eid;
      if(action !== "delete") {
        update = {
          ['events/' + key]: object,
          ['roles/' + this.firebaseAuthentication.uid + '/' + key]: object
        }
      } else {
        console.log("delete event", key);
        update = {
          ['events/' + key]: null,
          ['roles/' + this.firebaseAuthentication.uid + '/' + key]: null,
          ['parts/' + key]: null,
          ['steps/' + key]:null
        }
      }
    } else if(type === "parts") {
      key = (key) ? key : pid;
      if(action !== "delete") {
        update = {
/************ . Here is the update object . ***********/
          ['parts/' + eid + '/' + key]: object
        }
      } else {
        update = {
          ['parts/' + eid + '/' + key]: null,
          ['steps/' + eid + '/' + key]: null
        }
      }
    } else if(type === "steps") {
      key = (key) ? key : sid;
      if(action !== "delete") {
        update = {
          ['parts/' + eid + '/' + pid + '/steps/' + key]: object,
          ['steps/' + eid + '/' + pid + '/' + key]: object
        }
      } else {
        update = {
          ['parts/' + eid + '/' + pid + '/steps/' + key]: null,
          ['steps/' + eid + '/' + pid + '/' + key]: null
        }
      }
    }
    console.log(object, update);
    return new Promise((resolve, reject) => {
/**************** . Finally the actual update function ************/
      this.ref.update(update).then(success => {
        resolve(success);
      }, error => {
        reject(error);
      });
    });
  }

Это в основном итерация, конкретная комбинация action/type - это edit/part.

Из того, что я прочитал об update() firebase update(), он не должен быть разрушительным для любых данных в объекте, который он не трогает. Это действует как set(), но я не хочу этого явно.

Какие-нибудь мысли? Фрэнк?

  • 0
    Вы вставили целую кучу кода, и минимальное повторение было бы более полезным. Самое важное, что нужно помнить, это то, что вы должны поместить всю специфику в путь, разделенный косой чертой. Обновление будет перезаписывать все на уровне ключа, поэтому вы не можете делать вложенные объекты, если не хотите перезаписать все это.
  • 0
    @MichaelBleigh, да, я вставил много кода, но все это уместно (кроме двух других операторов обновления). Что касается обновления, если бы я поместил пустой элемент steps в этот объект, разве он не переписал бы то, что там? (не очень хороший пример, потому что шаги были бы во всем на этом этапе, но просто проверяя точку)
Показать ещё 2 комментария
Теги:
angular
firebase
ionic3
firebase-realtime-database

1 ответ

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

Из того, что я собираю из вашего кода, функция обновления работает так, как я ожидал бы (от опыта, а не от документации). Я хочу сказать, что обновление по ключу путем установки его на объект делает именно это, оно устанавливает значение ключа для объекта, который вы передали. Пример:

пользователей:

  • Nik

    • Возраст: 18
    • Идентификатор: 1
  • Джордж

    • Возраст: 29
    • ID: 2

пусть obj = {age: 24};

вызывающее обновление ({nik: obj}) фактически установило бы, чтобы nik имел значение объекта, который вы предоставляете (таким образом, удаляя id). Стенды, чтобы рассуждать правильно? Хорошо, что firebase говорит об обновлении:

Если вы хотите одновременно писать нескольким дочерним элементам базы данных, не перезаписывая другие дочерние узлы, вы можете использовать метод обновления, как показано ниже:

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

  • 0
    Мои эксперименты показывают то же самое. А также омерзительные комментарии Майкла выше. Вы правы, что звучит немного странно, как они это произносят, но указывать это имеет смысл. По сути, дочерние узлы - это больше элементы верхнего уровня, а не дочерние объекты редактируемого объекта. Теперь понятно

Ещё вопросы

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