Подтвердить что ты не робот

Правильный способ хранения значений массива в 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 не хранит массивы изначально, однако в этом случае это не имеет значения, просто как мне хотелось бы видеть мои данные.

4b9b3361

Ответ 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);