0

Ошибка Firebase.update: первый аргумент содержит undefined в свойстве

12

У меня есть простая функция Firebase, которая обновляет некоторые данные. Однако интерпретатор сообщает, что первый аргумент содержит "undefined" в свойстве 'users.tester1'. Можете, пожалуйста, помочь мне разобраться в этом?

Вот код функции:

var objify = function() {
  var rv = {};
  for (var i = 0; i < arguments.length; ++i)
    rv[arguments[i]] = rv[arguments[i + 1]];
  return rv;
}

addUser("tester1", []);

var addUser = function(name, edges){
  if (!checkIfUsernameExists(name) && !checkIfNodeNameExists(name) && !checkIfEdgeNameExists(name)) {
    var time = Firebase.ServerValue.TIMESTAMP;

    // ЗДЕСЬ: Я думаю, что ошибка на этой строке 
    refs.users.update(objify(name, "filler"));

    refs.users.child(name).set({
      "id": time,
      "edges": "filler"
    });
    refs.users.child(name).child("edges").update({
      "to": "filler",
      "from": "filler"
    });

    addNode(new Node(name, time, name));

    for (var e in edges) {
      refs.users.child(name).child("edges/to").update(objify(edges[e].name, true));
      addEdge(new Edge(edges[e].name, time, edges[e].to, edges[e].arrows));
      //TODO добавить "from" edge, чтобы знать, кто хочет вас съесть
    }
    refs.users.child(name).child("edges/to").set({"filler": null});
  } else {
    alert("имя пользователя/узла/ребра уже занято.");
  }
};

Проблема в том, что когда я пытаюсь обновить refs.users, интерпретатор говорит, что свойство 'users.tester1' имеет значение "undefined". Что может быть причиной этой ошибки и как я могу её исправить?

5 ответ(ов)

0

Когда вы передаете объект в Firebase, значения его свойств могут быть либо значением, либо null (в этом случае свойство будет удалено). Однако они не могут быть undefined, что, судя по ошибке, вы и передаете.

Попробуйте следующий фрагмент кода в изоляции, чтобы увидеть проблему:

var objify = function() {
  var rv = {};
  for (var i = 0; i < arguments.length; ++i)
    rv[arguments[i]] = rv[arguments[i+1]];
  return rv;
}
objify("name", "filler")

Результат будет следующим:

{name: undefined, filler: undefined}

Судя по всему, вы хотите передавать пары ключ/значение в функцию objify в качестве чередующихся параметров. В этом случае вам нужно изменить функцию на следующую:

var objify = function() {
  var rv = {};
  for (var i = 0; i < arguments.length; i+=2)
    rv[arguments[i]] = arguments[i+1];
  return rv;
}
objify("name", "filler")

Теперь результат будет таким:

{name: "filler"}

Таким образом, ваша функция теперь правильно создает объект с нужными значениями.

0

Чтобы убедиться, что ваш объект не содержит неопределенных свойств, используйте этот простой трюк:

JSON.parse(JSON.stringify(ВашиДанныеJson));

Это позволяет создать глубокую копию вашего объекта, устраняя все неопределенные свойства.

Для получения дополнительной информации, посмотрите на этот кодPen: http://codepen.io/ajmueller/pen/gLaBLX

0

Ошибка, которую вы получаете, связана с тем, что библиотека Firebase не позволяет обновлять свойства с неопределенным значением (undefined). Однако, значения null допускаются и рассматриваются как "игнорируемые" при обновлении.

Ваша задача заключается в том, чтобы создать "сырой" трансформер, который будет игнорировать все методы и свойства прототипа, а также преобразовывать undefined в null или полностью удалять свойства с неопределенными значениями.

В вашем коде, ошибка, скорее всего, возникает на этой строке:

refs.users.update(objify(name, "filler"));

Убедитесь, что функция objify корректно обрабатывает значения, передаваемые в нее, и не возвращает свойства с undefined. В текущем варианте, если objify возвращает объект, содержащий свойства с неопределенными значениями, вызов update вызовет ошибку.

Вот, как можно улучшить трансформер для удаления свойств с undefined значениями:

function cleanObject(obj) {
    return Object.entries(obj)
        .reduce((acc, [key, value]) => {
            if (value !== undefined) {
                acc[key] = value === null ? null : value; // сохраняем null как есть
            }
            return acc;
        }, {});
}

Замените вызовы, где вы используете objify, на:

refs.users.update(cleanObject(objify(name, "filler")));

И в других местах, например:

refs.users.child(name).set(cleanObject({
    "id": time || null,
    "edges": "filler" || null
}));

refs.users.child(name).child("edges").update(cleanObject({
    "to": "filler" || null,
    "from": "filler" || null
}));

Таким образом, вы избавитесь от ошибок связанных с обновлением значений, равных undefined.

0

Как было сказано выше, чтобы значения undefined сохранялись как пустые значения в Firebase, вам нужно заменить их на null.

Я использую следующий подход для исправления всех вложенных значений:

// Функция для поиска и замены
const replaceAll = (s = "", f = "", r = "") => 
    s.replace(new RegExp(f.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), r);

// Для сохранения данных в Firebase
firebase.database().ref(`path`).update(
    JSON.parse(replaceAll(JSON.stringify(val), "undefined", "null"))
);

Этот код сначала преобразует объект в строку JSON, заменяет все вхождения undefined на null, а затем парсит строку обратно в объект и обновляет данные в Firebase.

0

Чтобы получить значение uid из объекта firstPaymentsData, вы можете использовать метод Object.keys(), как указано в вашем примере:

var key1 = Object.keys(firstPaymentsData)[0], // Получаем первый ключ из первого уровня
    key2 = Object.keys(firstPaymentsData[key1])[0], // Получаем первый ключ из второго уровня
    uid  = firstPaymentsData[key1][key2].uid; // Получаем значение uid

Данный код извлекает первый ключ из объекта firstPaymentsData, затем извлекает первый ключ из вложенного объекта и, наконец, получает значение uid. Убедитесь, что структура вашего объекта соответствует ожиданиям, иначе могут возникнуть ошибки.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь