2017-02-27 2 views
1

Ich bin neu hier. Ich kann keine Daten aus der Firebase-Datenbank abrufen. Ich möchte Name und food_items jeder Kategorie abrufen.Wie kann man Daten aus der Firebase Echtzeitdatenbank in Android abrufen?

mydatabase

{ 
    "categories" : { 
     "category1" : { 
      "name" : "Babyfood" 
     }, 
     "category2" : { 
      "name" : "Dairy" 
     }, 
     "category3" : { 
      "food_items" : { 
      "item1" : true, 
      "item2" : true 
      }, 
      "name" : "Fruits" 
     } 
     }, 
     "food_items" : { 
     "item1" : { 
      "category" : "category3", 
      "name" : "Apple" 
     }, 
     "item2" : { 
      "category" : "category3", 
      "name" : "Banana" 
     } 
    } 
} 

FoodCategory.java

public class FoodCategory implements Serializable{ 

    String name; 
    FoodItem food_items; 

    public FoodCategory(){} 

    public FoodCategory(String name, FoodItem food_items) { 
     this.name = name; 
     this.food_items = food_items; 
    } 

    public FoodItem getFoodItems() { 
     return food_items; 
    } 

    public String getName() { 
     return name; 
    } 

    public FoodCategory(FoodCategory category){ 
     this.name = category.getName(); 
     this.food_items = category.getFoodItems(); 
    } 

} 

FoodItem.java

public class FoodItem { 
    String name; 

    public FoodItem(FoodItem foodItem) { 
     this.name = foodItem.getName(); 
    } 

    public String getName() { 
     return name; 
    } 
} 

meine hier Code für Daten jeder Kategorie

mRootRef = FirebaseDatabase.getInstance().getReference(); 
    mCategoryRef = mRootRef.child("categories"); 
    mCategoryRef.addValueEventListener(new ValueEventListener() { 

     ArrayList<FoodCategory> values = new ArrayList<>(); 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      for (DataSnapshot snapshot: dataSnapshot.getChildren()){ 
       FoodCategory c = snapshot.getValue(FoodCategory.class); 
       Log.d("Categories: ", c.name + " " + c.food_items); 
       values.add(c); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

Es gibt richtigen Wert für die Kategorie Namen, aber null für food_items abruft.

Antwort

0

In Ihrem FoodCategory Modell, die Sie erwähnen, dass es nur SINGLE Wert von FoodItem hat:

public class FoodCategory implements Serializable{ 
    String name; 
    FoodItem food_items; 
    ... 
} 

Und durch einen Blick auf Ihre Datenbankstruktur, sollte es sein eine Liste/Array von FoodItem richtig? Und wenn Ihr FoodItem nur Name String als Schlüssel und boolean true als Wert enthält (es ist immer wahr, nicht wahr?), Dann vielleicht sollten Sie es HashMap machen, wie diese

public class FoodCategory implements Serializable{ 
    String name; 
    HashMap<String, Boolean> food_items; 
    ... 
} 

Auf diese Weise brauchen Sie nicht die FoodItem benutzerdefiniertes Objekt (Oder Sie immer noch, dass verwenden können und food_items eine Liste/Array von FoodItem benutzerdefinierte Objekt machen.

EDIT

wie ursprüngliche Plakat Sieht magisch „wissen“, was er zu tun und beantworten selbst (oder?). aber für diejenigen, die hier das gleiche Problem und suchen nach Antwort haben, ist diese Erklärung für Sie

die Datenbankstruktur.

{ 
    "categories" : { 
     "category1" : { 
      "name" : "Babyfood" 
     }, 
     "category2" : { 
      "name" : "Dairy" 
     }, 
     "category3" : { 
      "food_items" : { 
      "item1" : true, 
      "item2" : true 
      }, 
      "name" : "Fruits" 
     } 
     }, 
     "food_items" : { 
     "item1" : { 
      "category" : "category3", 
      "name" : "Apple" 
     }, 
     "item2" : { 
      "category" : "category3", 
      "name" : "Banana" 
     } 
    } 
} 

im Code sa MPLE, die in Frage gestellt, es liest Wert auf categories und Suche nach categories/???/food_items für Wert. Bitte beachten Sie, dass food_items ich hier erwähnen, sind die, die im Innern der categories nicht food_items Eltern von item1 und item2.

So natürlich wird es null für das erste und dritte Kind enthalten, da es in der Tat keinen Wert hat.Aber der zweite wird zwei Werte haben:

{ "item1":true, "item2":true } 

Hinweis: es 2 Werte hat, so empfehle ich HashMap es zu lesen, weil ursprüngliches Plakat es als einziger Wert lesen.

Von dort wissen wir, was falsch ist. Dann wollen Sie wahrscheinlich Details von item1 und item2 bekommen, weil es nur Boolesche enthält (es ist wie ein Fremdschlüssel in SQL). Dann solltest du den Wert food_items/??? lesen und los gehts.

+0

Jede Kategorie enthält den Namen der Kategorie und die Liste der Lebensmittel. Zum Beispiel enthält Kategorie 3 "Früchte", da der Name der Kategorie und Liste von Nahrungsmitteln {Apfel, Banane} ist (d. H. Artikel 1, Artikel 2 von Lebensmittelartikeln). foodItems von food_categories sind FoodItems Objekte. Ich habe ** HashMap food_items ** verwendet, aber immer noch find ich food_items als null. – user2970035

+0

Danke für die Erklärung. Es war hilfreich. Kannst du mir sagen, wie man auf verschachtelte Schlüssel wie category1 zugreift (es kann irgendein zufälliger Schlüssel sein) und ich weiß nicht, warum mein Konstruktor nicht mit diesem Code instanziiert wird ** snapshot.getValue (FoodCategory.class) **. Ich musste es mit einem neuen Betreiber initialisieren. – user2970035

+0

Sie müssen wissen, welchen Schlüssel Sie erhalten möchten, auch wenn es zufällig ist. Dann mach es so 'mRootRef.child ("categories/category1") '. Werfen Sie einen Blick auf [diese Dokumentation] (http://stackoverflow.com/documentation/firebase-database/9242/reading-data/28681/understanding-which-data-referenced-by-getreference#t=201702282214462701557) – koceeng

0

Zum Iterieren aller untergeordneten Elemente eines Knotens verwenden Sie stattdessen ChildEventListener. Lassen Sie sich nicht durch den Methodennamen 'onChildAdded' verwirren, er wird alle Einträge beim ersten Mal durchlaufen.

mCategoryRef.addChildEventListener(new ChildEventListener() { 
     @Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
      FoodCategory c = dataSnapshot.getValue(FoodCategory.class); 
      Log.d("Categories: ", c.name + " " + c.food_items); 
      values.add(c); 
     } 

     @Override 
     public void onChildChanged(DataSnapshot dataSnapshot, String s) { 

     } 

     @Override 
     public void onChildRemoved(DataSnapshot dataSnapshot) { 

     } 

     @Override 
     public void onChildMoved(DataSnapshot dataSnapshot, String s) { 

     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

Quelle: https://firebase.google.com/docs/database/android/lists-of-data

+0

food_items immer noch null. – user2970035

+0

Ihr Datenmodell ist anders. Das food_item in Kategorie 3 hat ein Array von booleschen Werten, aber in Ihrem FoodItem-Modell haben Sie den String-Namen definiert. Ändern Sie es, damit es funktioniert. –

Verwandte Themen