2013-07-29 5 views
8

Używam Firebase do przechowywania danych w projekcie Android i używania Firebase Java API do przetwarzania danych. Nie jestem pewien, czy robię to tak skutecznie, jak to możliwe, i chciałbym poradzić się w sprawie najlepszych praktyk dotyczących pobierania i formatowania danych. Moja Firebase repozytorium wygląda tak ....Najlepszy sposób na odzyskiwanie/formatowanie danych za pomocą interfejsu API Java Firebase

-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) - ... 

Tak więc, na przykład tutaj Próbuję uzyskać wszystkie dane z sondażu do listy ankietę nazwę, to nazwy wyborów, a nazwy kandydujących oraz numer głosów na każde wybory. I dostać sondażach poziom DataSnapshot podczas funkcji OnCreate() mojej głównej działalności jak ten ...

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

      } 
     }); 
    } 

Potem przejdź do zapoznania się z pojedynczych fragmentów danych muszę przez kolejno nazywając getValue() na DataSnapshots i sprawdzanie klawiszy powstałego 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"); 
        } 
       } 
      }; 
     } 
    } 

wydaje się to dość nudny sposób, aby drążyć struktury danych, a ja zastanawiałem się, czy istnieje lepszy sposób.

Widziałem metodę getValue(java.lang.Class<T> valueType) w dokumentacji, ale nie byłem w stanie jej uruchomić w moim przypadku, ponieważ pracuję z obiektami złożonymi, a nie tylko z kontenerami dla typów pierwotnych. W jaki sposób funkcja wie, jakie dane należy przypisać do zmiennych składowych obiektu modelu? Czy pasuje do nazw kluczy ze zmiennymi składowymi, a zatem czy muszą one być dokładnie takie same, z uwzględnieniem wielkości liter? W jaki sposób ma to związek z wygenerowanymi kluczami o nazwach Firebase, takich jak produkowane podczas przesyłania do wersji List? Jak konstruować obiekty modelu dla złożonych obiektów?

Odpowiedz

18

Metoda getValue(java.lang.Class valueType) jest zgodna z tymi samymi regułami, co biblioteka odwzorowania obiektów Jacksona (jest to funkcja, której używamy wewnętrznie: http://wiki.fasterxml.com/JacksonInFiveMinutes). Zatem twoje klasy Java muszą mieć domyślne konstruktory (bez argumentów) i pliki pobierające dla właściwości, które chcesz przypisać (https://www.firebase.com/docs/java-api/javadoc/com/firebase/client/DataSnapshot.html#getValue(java.lang.Class)). Krótko mówiąc, nazwy kluczy w Firebase muszą być zgodne ze zmiennymi składowymi.

Przykład użycia obiektów złożonych, w tym listę, patrz: AndroidDrawing. W szczególności klasa Segment zawiera listę instancji Point. Jest jeden haczyk z wykorzystaniem list danych wygenerowanych metodą .push(). Ponieważ generowane nazwy kluczy są ciągami znaków, dzięki czemu mogą być unikatowe dla różnych klientów, deserializują je, a nie Map s, a nie List. Jeśli jednak wykonasz iterację po numerze dataSnapshot.getChildren(), zostaną one zwrócone w kolejności.

Ponadto, jeśli nie chcesz deserializować w HashMap, możesz użyć metody child() w DataSnapshot. Na przykład:

 

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

W tym przykładzie, wszelkie wartości, które nie istnieją zostaną zwrócone jako null.

Nadzieję, że pomaga!

+0

Chłodny dzięki Greg. Daj mi kilka godzin, aby wrócić do domu i spróbować wdrożyć w ten sposób. Dzięki! – MassStrike

+0

Dobra, wszystko, czego potrzebuję, aby zacząć. Dzięki Greg, doceń szybkie wsparcie. – MassStrike

+0

Przepraszam, że wychodzę ze starego wątku, ale używam GeoFire razem z Firebase, a klasa Geolocation nie zapewnia domyślnego konstruktora. Jak więc powinienem dokonać deserializacji tego rodzaju zajęć? Czy jest tam osadzona fabryka deserializatorów? Dzięki ! – Leonardo

1

publicznego T getValue (klasa ValueType)

1.Klasa musi mieć domyślny konstruktor, który nie przyjmuje argumentów.

2. Klasa musi definiować publiczne wywołania dla właściwości, które mają zostać przypisane. Właściwości bez publicznej getter zostaną ustawione na wartości domyślne, gdy instancja jest rozszeregować

Sprawdź to z: this source że to pomoże

detail

Powiązane problemy