首页 > 解决方案 > 从 RealtimeDatabase 读取特定节点

问题描述

我的 Firebase RealtimeDatabase 包含一个名为 Records 的表。在该表中有 FirebaseUser Uid,在每个 Uid 中都有日期,在每个日期中都有一个产品列表。 这是来自 firebase 控制台的示例。

在名为 DailyTableActivity 的活动中,有一个提示 DatePickerDialog 的按钮和一个 ListView 元素,该元素应显示已连接用户的对话框(或当前日期)中特定日期的产品。

这是类产品

    import java.util.Comparator;

public class Product  {
    public Product() {

    }

    private String id;
    private String Name;
    private double Cal;
    private double Carb;
    private double Prot;
    private double Fat;
    private String Unit;
    private int Def;

    public Product(String name, int cal, int carb, int prot, int fat, String unit, int def,String id) {
        Name = name;
        Cal = cal;
        Carb = carb;
        Prot = prot;
        Fat = fat;
        Unit = unit;
        Def = def;
        this.id=id;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public double getCal() {
        return Cal;
    }

    public void setCal(double cal) {
        Cal = cal;
    }

    public double getCarb() {
        return Carb;
    }

    public void setCarb(double carb) {
        Carb = carb;
    }

    public double getProt() {
        return Prot;
    }

    public void setProt(double prot) {
        Prot = prot;
    }

    public double getFat() {
        return Fat;
    }

    public void setFat(double fat) {
        Fat = fat;
    }

    public String getUnit() {
        return Unit;
    }

    public void setUnit(String unit) {
        Unit = unit;
    }

    public int getDef() {
        return Def;
    }

    public void setDef(int def) {
        Def = def;
    }


    public static Comparator<Product> productComparator= new Comparator<Product>() {
        @Override
        public int compare(Product o1, Product o2) {
            return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
        }
    };
}

这是我读取数据的代码:

public void getRecordOfDate( String date , final DataStatus dataStatus)
{
    final String currId= FirebaseAuth.getInstance().getCurrentUser().getUid();
    date="D_"+date;
    DatabaseReference recordsOfUser=FirebaseDatabase.getInstance().getReference().child("records").child(currId);
    DatabaseReference dateRef=recordsOfUser.child(date);
    dateRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
            if (snapshot.exists()){
                List<String> keys = new ArrayList<>();
                for (DataSnapshot keyNode : snapshot.getChildren()) {
                    products.clear();
                    keys.add(keyNode.getKey());
                    Product product = keyNode.getValue(Product.class);
                    Log.d("DATA_SUCCESS", "Adding product " + product.getName());
                    products.add(product);
                    dataStatus.DataIsLoaded(products, keys);
            }
            }
        }

        @Override
        public void onCancelled(@NonNull @NotNull DatabaseError error) {

        }
    });


}

dataStatus 是一个运行良好的接口,这就是我没有在此处包含它的原因。我认为我的主要问题来自不存在的日期,但是即使我选择了一个存在的日期,它也不起作用。

我确实认为有必要提一下,如果我选择硬代码中存在的日期,则会读取数据,如下所示:

DatabaseReference dateRef=recordsOfUser.child("D_21_05_2021");

我非常感谢任何帮助和支持,我希望你能帮助我找到解决这个问题的方法,因为我对 NoSQL 数据库不是很熟悉,我想探索 Realtime 的可能性。

标签: javaandroidfirebase-realtime-databasenosql

解决方案


String public void getRecordOfDate( String date , final DataStatus dataStatus){
final String currId= FirebaseAuth.getInstance().getCurrentUser().getUid();
date="D_"+date;
DatabaseReference recordsOfUser=FirebaseDatabase.getInstance().getReference().child("records").child(currId);
DatabaseReference dateRef=recordsOfUser.child(date);
dateRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
        if (snapshot.exists()){
            List<String> keys = new ArrayList<>();
            if(snapshot.hasChild(date)){
            for (DataSnapshot keyNode : snapshot.getChildren()) {
                //products.clear();
                keys.add(keyNode.getKey());
                //Product product = keyNode.getValue(Product.class);
                String Name = keyNode.child("name").getValue().toString();
                double Cal = Double.parseDouble(keyNode.child("cal").getValue().toString());
                double Carb = Double.parseDouble(keyNode.child("carb").getValue().toString());
                double Prot = Double.parseDouble(keyNode.child("prot").getValue().toString());
                double Fat = Double.parseDouble(keyNode.child("fat").getValue().toString());
                String Unit = keyNode.child("unit").getValue().toString();
                int Def = Integer.parseInt(keyNode.child("def").getValue().toString());
                String Id = keyNode.getKey();
                Product product = new Product(Name, Cal, Carb, Prot, Fat, Unit, Def, Id);
                Log.d("DATA_SUCCESS", "Adding product " + product.getName());
                products.add(product);
                dataStatus.DataIsLoaded(products, keys);
        }
        }else{System.out.print("Date does not exist")}
        }
    }

    @Override
    public void onCancelled(@NonNull @NotNull DatabaseError error) {

    }
});}

试试这样,希望它有效!然后你应该能够使用你的列表来放置数据TextView和那种东西。我注释products.clear()了行以将列表保存在“本地”上,而不是在每次迭代时将其删除。如果这对您不起作用,则问题必须出在您的日期收集方法或此处date="D_"+date;


推荐阅读