2014-11-25 16 views
12

Ho un nome della canzone, con le valutazioni che sto risparmiando per questo. E sembra una foto qui sotto, dato che sto usando push() per memorizzare ogni nuovo voto.Un modo corretto per archiviare valori come array in Firebase

data example

Ma quello che mi piacerebbe vedere è, ratings come un array di oggetti, ciascuno dei quali contiene qualcosa di simile:

voter: { 
    ip: "1.1.1.1", 
    stars: 3, 
} 

Così rating chiave finirebbe per essere qualcosa di simile a questo:

rating: [{ip: "1.1.1.1", stars: 3}, ...] 

Quindi posso abilitare un solo voto per indirizzo IP. Quello che non ho potuto trovare nei documenti Firebase, è come aggiungere a una chiave esistente, in questo caso rating (ma sarebbe [lista, come]) - un nuovo hash come quello sopra. Perché crea automaticamente il valore hash-key e voglio aggiungere a una chiave esistente.

EDIT: sono consapevole del fatto, che Firebase non memorizza le matrici in modo nativo, tuttavia in questo caso non importa, è solo come mi piacerebbe vedere i miei dati.

risposta

14

Attualmente si utilizza push per aggiungere nuovi figli, che genera automaticamente un nome per il nuovo nodo che è "garantito" per essere univoco tra più client. Metodo

ref.push({ ip: userIP, stars: userStars }); 

di Firebase push è un ottimo modo per avere più clienti aggiungendo elementi a una raccolta ordinata. Se vuoi ottenere lo stesso risultato usando gli array, dovresti sincronizzare la lunghezza dell'array tra i client. La generazione del nome di Firebase non richiede un simile overhead, quindi è normalmente preferibile mantenere una raccolta ordini su più client.

Ma nel tuo caso, non sembra che desideri una raccolta "solo aggiunta" ordinata. Sembra che tu consideri l'indirizzo IP come un'identificazione di ciascun nodo. In tal caso vorrei utilizzare l'indirizzo IP come base per il nome del nodo:

votes 
    "1.1.1.1": 3 
    "1.2.3.4": 5 
    "1.7.4.7": 2 

Si dovrebbe raggiungere questo obiettivo con:

ref.child(userIP).set(userStars); 

Se si desidera leggere in seguito tutti i voti in un array, è può fare:

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'); 
}) 
+0

Grazie! Sto avendo lo stesso problema, questo ha funzionato per me. – KaoriYui

0

ho voluto creare una funzione riutilizzabile per aggiungere/salvare qualsiasi oggetto con un nodo radice (anche se che ha una matrice di dati a qualsiasi livello all'interno dell'oggetto). Quindi mi sono inventato questo.(Non sono sicuro se è conforme alle migliori pratiche, ma ha funzionato abbastanza liscio)

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; 
     } 
    } 

Quindi, per aggiungere nuovi utenti sotto root users, si chiama:

SaveWholeData("users", oUserInfo, true); 

e aggiornamento utente esistente:

SaveWholeData("users"+"/"+ oUserInfo.genKey, oUserInfo, true); 
Problemi correlati