我是新来的。我无法从Firebase数据库中检索数据。我想检索每个类别的名称和food_items
。
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;
}
}
以下是我检索每个类别数据的代码
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) {
}
});
它返回类别名称的正确值,但food_items
为空。
答案 0 :(得分:0)
对于迭代节点的所有子节点,请改用ChildEventListener。 不要对方法名称&#39; onChildAdded&#39;感到困惑。 ,它将第一次进入所有条目。
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) {
}
});
来源:https://firebase.google.com/docs/database/android/lists-of-data
答案 1 :(得分:0)
在您的FoodCategory
模型中,您提到它只有 SINGLE 值FoodItem
:
public class FoodCategory implements Serializable{
String name;
FoodItem food_items;
...
}
通过查看您的数据库结构,它应该是FoodItem
的列表/数组对吗?如果你的FoodItem
只包含名称字符串作为键,布尔值作为值(它总是为真,对吗?)那么你可能应该把它作为HashMap
,就像这样
public class FoodCategory implements Serializable{
String name;
HashMap<String, Boolean> food_items;
...
}
这样,您不需要FoodItem
自定义对象。 (或者你仍然可以使用它并使food_items
成为FoodItem
自定义对象的列表/数组。
修改强>
看起来原始海报神奇地“知道”该做什么并自己回答(嗯?)。但是对于那些有同样问题并在这里寻找答案的人来说,这个解释适合你。
数据库结构:
{
"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"
}
}
}
在发布的相关代码示例中,它会读取categories
上的值并搜索categories/???/food_items
的值。请注意,我在此处提到的food_items
是categories
而非food_items
父item1
和item2
内的{/ 1}}。
当然,对于第一个和第三个孩子,它将包含null
,因为它实际上没有价值。但第二个将有2个值:
{ "item1":true, "item2":true }
注意:它有2个值,因此我建议使用
HashMap
来阅读它,因为原始海报会将其读作单个值。
从那里,我们知道出了什么问题。之后,您可能希望获得item1
和item2
的详细信息,因为它只包含布尔值(它就像sql中的外键)。那么你应该阅读价值food_items/???
然后你就去了。