簡體   English   中英

搜索 FireBase 實時數據庫

[英]Searching FireBase realtime database

firebase 實時新手,我正在嘗試制作 android 宏跟蹤應用程序。 當我嘗試運行下面的代碼時,我得到“No setter/field for -M6v0ZiU6tLuBDlmcuEe found on class com.example.pttracker.nutritionEntry”

查看有關堆棧溢出的其他問題,有人說這可能是因為 valueEventListener 沒有正確定位,但是......不是嗎? 我正在鑽取食物條目/營養條目,但我不知道如何鑽得更深。 沒有辦法匿名給孩子打電話嗎? 我嘗試調用 childEventListener 而不是 valueEventListener,其他所有內容都相同,但我不再收到該消息,但我仍然無法檢索我想要的數據。

我的 JSON 結構:

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 循環,以便我獲得兒童帖子的價值而不是數據快照,這是一個問題。 我還將代碼更新為 go 到正確的 UID,然后是營養條目,這也會導致問題。 我不再收到相同的消息,但我仍然什么也沒得到。 當我 go 進入調試器時,未調用 onDataChange ,因此 resultsList 為空。 onCancled 從來沒有被稱為更新代碼,這里是暴露的 JSON 以及我的 NutritionEntry class 的屏幕截圖。 它具有默認構造函數、所有參數的構造函數、所有 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;
    }




}

第二次編輯:

現在我的數據庫規則是 read: true 和 write: true 所以我有權限。

最終編輯:

在用 Hasan 對以下各種問題進行了多次故障排除之后,最后一個難題是我的變量和我的 getter/setter 都在我的 NutritionEntry class 中被聲明為 public。 將變量從公共訪問更改為默認訪問,這樣我終於可以從 Firebase 檢索條目。

首先不要這樣做:

if(userOrAll) {
allEntries = ref.child("Food Entries").orderByChild("foodTitle").equalTo(searchString);
}else{
allEntries = ref.child("Users").child("Nutrition entries").orderByChild("foodTitle").equalTo(searchString);
}

相反,決定你想要的 ref 是什么,假設你想閱讀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");

現在這很重要,請確保在您的 class 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);

更新:

在我看來,構建 object 時出現問題,請在 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);

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM