Можно ли переименовать ключ в базе данных 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);
});
});
}