firebase实时的新手,我正在尝试制作一个Android Macro跟踪应用。当我尝试运行以下代码时,我收到“在类com.example.pttracker.nutritionEntry上找不到-M6v0ZiU6tLuBDlmcuEe的设置程序/字段”
仔细检查堆栈溢出的其他问题,有人说这可能是因为valueEventListener的位置不正确,但是...不是吗?我正在深入研究食物条目/营养条目,但是我不知道该怎么做。没有办法匿名呼叫孩子吗?我尝试调用childEventListener而不是valueEventListener,其他所有方法都相同,但是我再也没有收到该消息,但是仍然无法检索到我想要的数据。
我的JSON结构:
我的代码:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query allEntries = ref.child("Users").child(profile.getProfileKey()).child("Nutrition entries").orderByChild("foodTitle").equalTo(search);
// Query for all entries with a certain child with value equal to something
final ArrayList<nutritionEntry> searchResults = new ArrayList<nutritionEntry>();
// Add listener for Firebase response on said query
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot post : dataSnapshot.getChildren() ){
nutritionEntry ex = post.getValue(nutritionEntry.class);
searchResults.add(ex);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("Error", "Search Cancled");
}
};
allEntries.addListenerForSingleValueEvent(valueEventListener);
if(searchResults.isEmpty()){
TableRow tr = new TableRow(nutritionTracker.this);
TextView tv1 = new TextView(nutritionTracker.this);
tv1.setText("No Results");
}else{
for(final nutritionEntry e : searchResults) {
//code to display the entries
}
非常感谢您的帮助和解释。
编辑:
到目前为止,谢谢您的帮助。 Per Hasan在下面的回答中,我更新了onDataChanged中的for循环,以便获得子发布而不是datasnapshot的值,这是一个问题。我还更新了代码,以转到正确的UID,然后输入营养条目,这也会引起问题。我不再收到相同的消息,但仍然什么也没收到。当我进入调试器时,不会调用onDataChange,因此resultsList为空。 onCancled从未被称为更新代码,这是暴露的JSON以及我的NutritionEntry类的屏幕截图。它具有默认构造函数,具有所有参数,所有getter和setter的构造函数,并且所有字段都与firebase中的内容匹配:
public class nutritionEntry {
public String date;
public String foodTitle;
public int calories;
public int protein;
public int totalCarb;
public int fiber;
public int sugar;
public int totalFat;
public int trans;
public int saturated;
public int unsaturated;
public String submittedBy;
public nutritionEntry(String date,String foodTitle, int calories, int protein, int totalCarb, int fiber, int sugar, int totalFat, int trans, int saturated, int unsaturated, String submitter) {
this.date = date;
this.foodTitle = foodTitle;
this.calories = calories;
this.protein = protein;
this.totalCarb = totalCarb;
this.fiber = fiber;
this.sugar = sugar;
this.totalFat = totalFat;
this.trans = trans;
this.saturated = saturated;
this.unsaturated = unsaturated;
this.submittedBy = submitter;
}
public nutritionEntry() {}
public String getDate() {
return date;
}
public String getFoodTitle() {
return foodTitle;
}
public int getCalories() {
return calories;
}
public int getProtein() {
return protein;
}
public int getTotalCarb() {
return totalCarb;
}
public int getFiber() {
return fiber;
}
public int getSugar() {
return sugar;
}
public int getTotalFat() {
return totalFat;
}
public int getTrans() {
return trans;
}
public int getSaturated() {
return saturated;
}
public int getUnsaturated() {
return unsaturated;
}
public String getSubmittedBy() {
return submittedBy;
}
public void setDate(String date) {
this.date = date;
}
public void setFoodTitle(String foodTitle) {
this.foodTitle = foodTitle;
}
public void setCalories(int calories) {
this.calories = calories;
}
public void setProtein(int protein) {
this.protein = protein;
}
public void setTotalCarb(int totalCarb) {
this.totalCarb = totalCarb;
}
public void setFiber(int fiber) {
this.fiber = fiber;
}
public void setSugar(int sugar) {
this.sugar = sugar;
}
public void setTotalFat(int totalFat) {
this.totalFat = totalFat;
}
public void setTrans(int trans) {
this.trans = trans;
}
public void setSaturated(int saturated) {
this.saturated = saturated;
}
public void setUnsaturated(int unsaturated) {
this.unsaturated = unsaturated;
}
public void setSubmittedBy(String submittedBy) {
this.submittedBy = submittedBy;
}
}
第二次编辑:
目前,我的数据库规则为:true和true:因此我具有权限。
最终编辑:
在对Hasan的以下各种问题进行了大量的故障排除之后,难题的最后一个事实是,我的变量和我的吸气剂/设置剂都在我的NutritionEntry课堂上宣布为公开。将变量从公共访问更改为默认访问即可完成操作,以便最终从Firebase检索条目。
答案 0 :(得分:1)
首先不要这样做:
if(userOrAll) {
allEntries = ref.child("Food Entries").orderByChild("foodTitle").equalTo(searchString);
}else{
allEntries = ref.child("Users").child("Nutrition entries").orderByChild("foodTitle").equalTo(searchString);
}
请改为决定您想要的裁判是什么,可以说您想阅读Users/UID/Nutrition entries/
:
//this is your ref for Nutrition Entries
String UID = FirebaseAuth.getInstance().getCurrentUser().getUid();
allEntries = ref.child("Users").child(UID).child("Nutrition Entries");
现在这很重要,请确保您的课程nutritionEntry
中的字段与Firebase中的名称匹配:
例如:
class nutritionEntry{
//these must be named exactly like in the database
String foodTitle;
......
......
......
......
//constructor must be generated for all
//getters and setters must be generated for all
}
最后读取值:
//this is your ref for Nutrition Entries
String UID = FirebaseAuth.getInstance().getCurrentUser().getUid();
allEntries = ref.child("Users").child(UID).child("Nutrition Entries");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren() ){
nutritionEntry ex = ds.getValue(nutritionEntry.class);
searchResults.add(ex);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
allEntries.addListenerForSingleValueEvent(valueEventListener);
更新:
在我看来,构造对象时出现问题,请在for循环中尝试此操作:
for(DataSnapshot ds : dataSnapshot.getChildren() ){
String date = ds.child("date").getValue(String.class);
String foodTitle = ds.child("foodTitle").getValue(String.class);
int calories = ds.child("calories").getValue(Integer.class);
int protein = ds.child("protein").getValue(Integer.class);
int totalCarb = ds.child("totalCarb").getValue(Integer.class);
int fiber = ds.child("fiber").getValue(Integer.class);
int sugar = ds.child("sugar").getValue(Integer.class);
int totalFat = ds.child("totalFat").getValue(Integer.class);
int trans = ds.child("trans").getValue(Integer.class);
int saturated = ds.child("saturated").getValue(Integer.class);
int unsaturated = ds.child("unsaturated").getValue(Integer.class);
String submittedBy = ds.child("submittedBy").getValue(String.class);
nutritionEntry entry = new nutritionEntry(date,foodTitle,calories,protein,totalCarb,fiber,sugar,totalFat,trans,saturated,unsaturated,submittedBy);
searchResults.add(entry);
}