Можно ли переименовать ключ в базе данных Firebase Realtime?

Мне было интересно, есть ли способ обновить значение ключа?

Давайте использовать следующие данные:

my data

Я использую set() для записи данных. Теперь я хочу, чтобы пользователь отредактировал свой bookTitle и он должен измениться в обоих местах. Я попытался с помощью update(), но я не могу заставить его работать. Я могу редактировать bookTitle в bookInfo НЕ на books.

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

Итак, есть ли способ обновить значение ключа? или есть лучший подход к этому? Я принимаю предложения. Спасибо!

Обновление: это то, что я сейчас использую для обновления названия книги внутри bookInfo

var bookName = document.getElementById('bookName').value;

firebase.database().ref('books/' + bookName + '/bookInfo').update({
    bookTitle : bookName
});

Ответ 1

Думаю, я вижу, что вы пытаетесь сделать. У Firebase нет понятия "переименование" части пути с помощью обновления. Вместо этого вам придется полностью удалить существующий node и воссоздать его. Вы можете сделать это так:

var booksRef = firebase.database().ref('books');
booksRef.child(oldTitle).once('value').then(function(snap) {
  var data = snap.val();
  data.bookInfo.bookTitle = newTitle;
  var update = {};
  update[oldTitle] = null;
  update[newTitle] = data;
  return booksRef.update(update);
});

Это приведет к удалению информации из books/oldTitle и повторного заполнения ее новым заголовком в books/newTitle.

Предостережение:. Это зависит от чтения данных и последующего обновления асинхронного обновления. Если вы, вероятно, одновременно столкнетесь с несколькими пользователями, работающими с одними и теми же данными, это может вызвать проблемы. Вы можете использовать transaction, чтобы сделать это атомарно, но если /books - это ресурс верхнего уровня со многими узлами, что может вызвать проблемы с производительностью.

Если один человек может редактировать данные за раз, это решение является прекрасным. Если нет, вы можете захотеть использовать не-пользовательский идентификатор, такой как идентификатор push.

Ответ 2

Вы можете экспортировать всю базу данных как JSON, переименовать ее в своем любимом редакторе, импортировать снова в firebase через опцию импорта/экспорта в правом верхнем углу окна консоли enter image description here

Ответ 3

Стоит отметить, что вы можете захватить уникальный ключ из функции push().

var booksRef = firebaseRef.database().ref('books');
var newBookRef = booksRef.push(myBookData);
var bookKey = newBookRef.key;

Источник: Firebase Docs - push()

Я не могу сказать со скриншота, где второй экземпляр bookTitle (это корневой элемент на скриншоте?), но если вы не хотите использовать push(), вы можете захватить данные в этом месте remove(), а затем снова вызовите set(), на этот раз с обновленным названием книги. Что-то вроде:

var bookRef = firebaseRef.database().ref('path/to/books/book1');

bookRef.on('value', function(snapshot) {
    var bookData = snapshot.val();
    var newData = {};
    var newTitle = 'NewTitle';

    bookData.bookInfo.bookTitle = newTitle;
    newData[newTitle] = bookData;
    firebaseRef.database().ref('path/to/books/' + newTitle).set(newData);

});

Ответ 4

Я бы все же использовал push(), что действительно правильный способ хранения нескольких дочерних объектов в категории - node в firebase, я думаю. Для поиска, подумали ли вы об этом на стороне клиента? Например, вы можете сохранить все ваши книжные объекты в книгах node и получить их для поиска локально, когда вам нужно.

Также, как упоминал ZenPylon, push() дает вам уникальный идентификатор, который вы также можете назначить в качестве опоры для каждого книжного объекта, чтобы каждая книга имела ссылку на то, где она хранится в базе данных.

Ответ 5

Мне очень понравился Майкл Блей, но НО...

При перемещении клавиш с одного уровня на другой это ограничивало меня по глубине, поэтому я лучше сделал эту функцию, которая даже позволяет дублировать (0) или перемещать (1) завершите ключ, просто изменив третий аргумент:

function mvFBkey(rtOrgn,rtDstn,rem){
  firebase.database().ref(rtOrgn).once('value').then(function(snap) {
    return firebase.database().ref(rtDstn).set(snap.val(),function(){
        if(rem)firebase.database().ref(rtOrgn).set(null);
    });
  });
}