2013-07-29 4 views
8

Ich verwende Firebase für die Datenspeicherung auf einem Android-Projekt, und die Firebase Java API verwenden, um mit Daten umzugehen. Ich bin mir jedoch nicht sicher, ob ich es so effizient wie möglich mache, und ich hätte gerne Tipps zu Best Practices für das Abrufen und Formatieren von Daten. Mein Firebase Repository sieht ungefähr so ​​aus ....Die beste Methode zum Abrufen/Formatieren von Daten mit Firebase Java API

-POLLS 
    NUMPOLLS - 5 
    (pollskey) - NAME - Poll1 
      NUMELECTIONS - 2 
      ELECTIONS 
       (electionskey) - NAME - Election1 
         NUMNOMINATIONS - 2 
         NUMVOTERS - 2 
         NUMBERTOELECT - 1 
         VOTERS - (votesrkey) - NAME - Charles 
             NUMBER - (678) 333-4444 
           . 
           . 
           . 
           (voterskey) - ... 
         NOMINATIONS - (nominationskey) - NAME - Richard Nixon 
               NUMBEROFVOTES - 2 
             . 
             . 
             . 
             (nominationskey) - ... 
      . 
      . 
      . 
      (electionskey) - ... 
    . 
    . 
    . 
    (pollskey) - ... 

So zum Beispiel hier Ich versuche, alle Daten, um aus einer Umfrage Umfrage Namen aufzuzählen, es Wahl Name ist, und der Kandidaten-Name und Nummer der Stimmen für jede Wahl. Ich erhalte die Urnen DataSnapshot während der OnCreate() Funktion meiner Haupttätigkeit wie dieses Niveau ...

private static final Firebase polls = pollsFirebase.child("Polls"); 
protected void onCreate(Bundle savedInstanceState) { 

     polls.addListenerForSingleValueEvent(new ValueEventListener() { 

      @Override 
      public void onDataChange(DataSnapshot snapshot) { 
       for (DataSnapshot child : snapshot.getChildren()) { 
        if (!child.getName().equals("NumPolls")) { 
         createPollTableAndHeaders(child); 
        } 
       } 

      } 
     }); 
    } 

Dann fahren Sie ich die einzelnen Teile der Daten ausgelesen ich nacheinander müssen getValue() auf DataSnapshots aufrufen, und von den oberen Tasten die resultierenden HashMaps ...

private void createPollTableAndHeaders(DataSnapshot poll) { 
    String pollName = ""; 
    int numPolls; 
    Object p = poll.getValue(); 
    if (p instanceof HashMap) { 
     HashMap pollHash = (HashMap) p; 
     if (pollHash.containsKey("Name")) { 
      pollName = (String) pollHash.get("Name"); 
     } 
     if (pollHash.containsKey("Elections")) { 
      HashMap election = (HashMap) pollHash.get("Elections"); 
      Iterator electionIterator = election.values().iterator(); 
      while (electionIterator.hasNext()) { 
       Object electionObj = electionIterator.next(); 
       if (electionObj instanceof HashMap) { 
        HashMap electionHash = (HashMap) electionObj; 
        if (electionHash.containsKey("Name")) { 
         String electionName = (String) electionHash.get("Name"); 
        } 
       } 
      }; 
     } 
    } 

Dies scheint einen ziemlich mühsamer Weg durch die Datenstruktur zu Drilldown, und ich frage mich, ob es ein besserer Weg.

Ich habe die getValue(java.lang.Class<T> valueType)-Methode in der Dokumentation gesehen, konnte sie aber in meinem Fall nicht zum Laufen bringen, da ich mit zusammengesetzten Objekten und nicht nur mit Containern für primitive Typen arbeite. Wie kann die Funktion wissen, welche Firebase Daten welchen Membervariablen eines Modellobjekts zugeordnet werden sollen? Passt es zu Firebase Schlüsselnamen mit Mitgliedsvariablen, und müssen diese daher exakt gleich sein, wobei die Groß-/Kleinschreibung beachtet werden muss? Wie würde das mit Firebase erzeugten Schlüsselnamen umgehen, die beim Drücken auf eine List erzeugt werden? Wie konstruiert man Modellobjekte für zusammengesetzte Objekte?

Antwort

18

Die Methode getValue(java.lang.Class valueType) folgt den gleichen Regeln wie die Jackson Object Mapping-Bibliothek (das verwenden wir intern: http://wiki.fasterxml.com/JacksonInFiveMinutes). Daher müssen Ihre Java-Klassen Standardkonstruktoren (keine Argumente) und Getter für die Eigenschaften haben, die Sie zuweisen möchten (https://www.firebase.com/docs/java-api/javadoc/com/firebase/client/DataSnapshot.html#getValue(java.lang.Class)). Kurz gesagt, die Schlüsselnamen in Firebase müssen den Mitgliedsvariablen entsprechen.

Ein Beispiel mit zusammengesetzten Objekten einschließlich einer Liste finden Sie unter AndroidDrawing. Insbesondere enthält die Klasse eine Liste von Point Instanzen. Es gibt einen Haken bei der Verwendung von Datenlisten, die mit der Methode .push() generiert wurden. Da die erzeugten Schlüsselnamen Strings sind, so dass sie über Clients hinweg eindeutig sein können, deserialisieren sie die Map s statt List s. Wenn Sie jedoch über dataSnapshot.getChildren() iterieren, werden sie in Reihenfolge zurückgegeben.

Wenn Sie nicht in eine HashMap deserialisieren möchten, können Sie außerdem die Methode child() für DataSnapshot verwenden. Zum Beispiel:

 

String pollName = poll.child("Name").getValue(String.class); 
DataSnapshot elections = poll.child("Elections"); 
for (DataSnapshot election : elections.getChildren()) { 
    String electionName = election.child("Name").getValue(String.class); 
} 
 

In diesem Beispiel werden alle Werte, die zurückgegeben als null nicht werden existieren.

Hoffe, dass hilft!

+0

Cooler Dank Greg helfen. Gib mir ein paar Stunden, um nach Hause zu kommen und versuche, so zu arbeiten. Vielen Dank! – MassStrike

+0

Ok cool, das ist alles, was ich brauche, um loszulegen. Danke Greg, danke für die schnelle Unterstützung. – MassStrike

+0

Es tut mir leid, einen alten Thread zu erstellen, aber ich verwende GeoFire zusammen mit Firebase und die Geolocation-Klasse bietet keinen Standardkonstruktor. Also, wie sollte ich fortfahren, diese Art von Klasse zu deserialisieren? Ist eine Deserializer-Factory eingebettet? Vielen Dank ! – Leonardo

1

public T getValue (Klasse valuetype)

1.Die Klasse muss einen Standardkonstruktor haben, der keine Argumente akzeptiert.

2. Die Klasse muss öffentliche Getters für die Eigenschaften definieren, die zugewiesen werden sollen. Eigenschaften ohne öffentliche Getter werden auf ihren Standardwert gesetzt werden, wenn eine Instanz

prüfen deserialisiert ist es aus: this source Es wird Sie

detail

Verwandte Themen