Правильный способ хранения значений массива в Firebase
У меня есть название песни, с оценками, которые я сохраняю для этого.
И это выглядит как pic bellow, поскольку я использую push()
для хранения каждого нового рейтинга.
![data example]()
Но я бы хотел видеть, ratings
как массив
объекты, каждая из которых содержит примерно следующее:
voter: {
ip: "1.1.1.1",
stars: 3,
}
Итак, rating
ключ будет выглядеть примерно так:
rating: [{ip: "1.1.1.1", stars: 3}, ...]
Затем я могу включить только один голос на каждый IP-адрес. Что я не мог найти в
Firebase
docs, как добавить к существующему ключу, в данном случае rating
(но это будет [list, like]) - a
новый hash
, как и выше.
Поскольку push()
автоматически создает значение hash-key
, и я хочу добавить
к существующему ключу.
EDIT:
Я знаю факт, что Firebase не хранит массивы изначально, однако в этом случае это не имеет значения, просто как мне хотелось бы видеть мои данные.
Ответы
Ответ 1
В настоящее время вы используете push
для добавления новых детей, который автоматически генерирует имя для нового node, которое "гарантировано" является уникальным для нескольких клиентов.
ref.push({ ip: userIP, stars: userStars });
Метод Firebase push
- отличный способ, чтобы несколько клиентов добавляли элементы в упорядоченную коллекцию. Если вы хотите сделать то же самое с использованием массивов, вам придется синхронизировать длину массива между клиентами. Генерация имени Firebase не требует таких накладных расходов, поэтому обычно предпочтительнее хранить коллекцию заказов для нескольких клиентов.
Но в вашем случае вам, похоже, не нужна упорядоченная коллекция "добавить только". Похоже, вы считаете, что IP-адрес является идентификацией каждого node. В этом случае я бы использовал IP-адрес в качестве основы для имени node:
votes
"1.1.1.1": 3
"1.2.3.4": 5
"1.7.4.7": 2
Вы выполнили бы это с помощью:
ref.child(userIP).set(userStars);
Если вы хотите впоследствии прочитать все голоса в массиве, вы можете сделать:
var votes = [];
votesRef.on('value', function(snapshot) {
snapshot.forEach(function(vote) {
votes.push({ ip: vote.key(), stars: vote.val() });
});
alert('There are '+votes.length+' votes');
})
Ответ 2
Я хотел создать функцию многократного использования для добавления/сохранения любого объекта под корнем node (даже если у него есть массив данных на любом уровне внутри объекта). Поэтому я придумал это. (Я не уверен, что соответствует лучшим практикам, но он работал довольно гладко)
SaveWholeData: function(sKey, oVal, bGenKey) {
bGenKey = bGenKey === undefined ? true: bGenKey;
var oOriginalProperty = angular.copy(oVal);
for (var property in oVal) {
if (oVal.hasOwnProperty(property) && oVal[property] instanceof Array) {
console.log(property);
oVal[property] = "$|$";
}
}
var sOwnRef = SaveDataByKey(sKey, oVal, bGenKey);
for (var property in oVal) {
if (oVal.hasOwnProperty(property) && oVal[property] === "$|$") {
oVal[property] = oOriginalProperty[property];
var updatedReference = sOwnRef + "/" + property;
SaveWholeData(updatedReference, oVal[property], false);
}
}
return true;
},
SaveDataByKey: function(sKey, oVal, bGenKey) {
if (bGenKey) {
var newPostKey = firebase.database().ref(sKey).push().key;
oVal.genKey = newPostKey;
firebase.database().ref(sKey).child(newPostKey).set(oVal);
return sKey + "/" + newPostKey;
}else{
firebase.database().ref(sKey).set(oVal);
return sKey;
}
}
Итак, чтобы добавить нового пользователя под root users
, вы вызываете:
SaveWholeData("users", oUserInfo, true);
и обновить существующий пользователь:
SaveWholeData("users"+"/"+ oUserInfo.genKey, oUserInfo, true);