Java 如何对多个子项执行查询?

Java 如何对多个子项执行查询?,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我正在尝试制作一个活动,显示类并在recyclerview中列出它们。但是,我在从firebase查询数据时遇到问题。在展示我的数据库结构之后,我将进一步解释。以下是我的数据库结构: "Classes": { "-Li9nBUgnFmCWqUmwV5W": { "class_info": { "date_clasname": "August 6, 2019", "room_number": "131",

我正在尝试制作一个活动,显示类并在recyclerview中列出它们。但是,我在从firebase查询数据时遇到问题。在展示我的数据库结构之后,我将进一步解释。以下是我的数据库结构:

"Classes": {
    "-Li9nBUgnFmCWqUmwV5W": {
        "class_info": {
            "date_clasname": "August 6, 2019",
            "room_number": "131",
            "subject": "Science",
            "teacher": "Ms.Henry",
            "id": "-Li9nBUgnFmCWqUmwV5W"
        }
    },
    "-Li9n_IYwbTNPdNAsTAu": {
        "class_info": {
            "date_clasname": "August 6, 2019",
            "room_number": "131",
            "subject": "Math",
            "teacher": "Ms.Henry",
            "id": "-Li9n_IYwbTNPdNAsTAu"
        }
    },
    "-Li9naUipsa865NBpZjW": {
        "class_info": {
            "date_clasname": "August 6, 2019",
            "room_number": "131",
            "subject": "Other",
            "teacher": "Ms.Henry",
            "id": "-Li9naUipsa865NBpZjW"
        }
    },
    "-Li9nbpwp2qchwmZRDP9": {
        "class_info": {
            "date_clasname": "August 6, 2019",
            "room_number": "131",
            "subject": "Technology",
            "teacher": "Ms.Henry",
            "id": "-Li9nbpwp2qchwmZRDP9"
        }
    },
    "-Li9ne0NDyjcB4SIWi1z": {
        "class_info": {
            "date_clasname": "August 6, 2019",
            "room_number": "131",
            "subject": "Social Studies",
            "teacher": "Ms.Henry",
            "id": "-Li9ne0NDyjcB4SIWi1z"
        }
    }
},
我试着按主题查询这些课程,只显示那些主题是“科学”的课程。我试过很多方法,但还是不知道怎么做。以下是我的活动代码:

public class Science_classes extends AppCompatActivity {
    private FirebaseDatabase database;
    private  DatabaseReference myRef, newmf;
   private List<Listdata> list;
   private RecyclerView recyclerview;
  String class_value = null;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_science_classes);
    recyclerview = (RecyclerView) findViewById(R.id.rview);
    database = FirebaseDatabase.getInstance();
    myRef = database.getReference("Classes");
    myRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {


            String id = dataSnapshot.getKey();

            Query query = myRef.child(id).child("class_info").orderByChild("subject").equalTo("Science");
            query.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    list = new ArrayList<>();
                    for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {

                        Class_model new_class = dataSnapshot1.getValue(Class_model.class);
                        String nameofclass = new_class.getDate_clasname();
                        String teacherofclass = new_class.getTeacher();
                        String roomnumberofclass = new_class.getRoom_number();
                        String class_key = new_class.getUid();
                        Listdata listdata = new Listdata(nameofclass, teacherofclass, roomnumberofclass, class_key);
                        //String name = userdetails.getName();
                        //String email = userdetails.getEmail();
                        //String address = userdetails.getAddress();
                        listdata.setDate_class(nameofclass);
                        listdata.setTeacher(teacherofclass);
                        listdata.setRnumber(roomnumberofclass);
                        list.add(listdata);
                    }
                    RecyclerviewAdapter2 recycler = new RecyclerviewAdapter2(list);
                    RecyclerView.LayoutManager layoutmanager = new LinearLayoutManager(Science_classes.this);
                    recyclerview.setLayoutManager(layoutmanager);
                    recyclerview.setItemAnimator(new DefaultItemAnimator());
                    recyclerview.setAdapter(recycler);
                }
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
        }



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

        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

        }

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

        }
    @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}


    }
public class Science\u class扩展应用程序活动{
私有FirebaseDatabase数据库;
私有数据库参考myRef,newmf;
私人名单;
私人回收站;
字符串类_值=null;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u science\u Class);
recyclerview=(recyclerview)findViewById(R.id.rview);
database=FirebaseDatabase.getInstance();
myRef=database.getReference(“类”);
myRef.addChildEventListener(新的ChildEventListener(){
@凌驾
公共void onChildaded(@NonNull DataSnapshot DataSnapshot,@null字符串s){
String id=dataSnapshot.getKey();
Query Query=myRef.child(id).child(“class_info”).orderByChild(“subject”).equalTo(“Science”);
query.addListenerForSingleValueEvent(新的ValueEventListener()){
@凌驾
public void onDataChange(@NonNull DataSnapshot DataSnapshot){
列表=新的ArrayList();
对于(DataSnapshot dataSnapshot1:DataSnapshot.getChildren()){
Class\u model new\u Class=dataSnapshot1.getValue(Class\u model.Class);
String nameofclass=new_class.getDate_clasname();
String teacherofclass=new_class.getTeacher();
字符串roomnumberofclass=new_class.getRoom_number();
String class_key=new_class.getUid();
Listdata Listdata=新的Listdata(班级名称、班级教师、班级房间号、班级钥匙);
//String name=userdetails.getName();
//字符串email=userdetails.getEmail();
//字符串地址=userdetails.getAddress();
setDate_类(类的名称);
settacher(类的教师);
listdata.setRnumber(roomnumberofclass);
list.add(listdata);
}
RecycleServiceAdapter2 recycler=新的RecycleServiceAdapter2(列表);
RecyclerView.LayoutManager LayoutManager=新的LinearLayoutManager(Science\u classes.this);
recyclerview.setLayoutManager(layoutmanager);
setItemAnimator(新的DefaultItemAnimator());
recyclerview.setAdapter(回收器);
}
@凌驾
已取消的公共void(@NonNull DatabaseError DatabaseError){
}
});
}
@凌驾
public void onChildChanged(@NonNull DataSnapshot DataSnapshot,@null字符串s){
}
@凌驾
公共void onChildRemoved(@NonNull DataSnapshot DataSnapshot){
}
@凌驾
public void onChildMoved(@NonNull DataSnapshot DataSnapshot,@null字符串s){
}
@凌驾
已取消的公共void(@NonNull DatabaseError DatabaseError){
}
});
}
}
我想我的问题可能是,我无法获取随机生成的id,并将其设置为我的孩子,而不是我的OnChildaded中的另一个孩子“class_info”。
谢谢大家!

您正在像这样构建查询:

Query query = myRef.child(id).child("class_info").orderByChild("subject").equalTo("Science");
这意味着通过
id
(我认为在您的JSON中没有显示)查找一个子对象,然后查找一个子对象
class_info
,然后在该子对象下查找每个子对象的
subject
属性并对其进行筛选。因此路径是
$id/class_info/*/subject
,其中
*
是要筛选和返回的子节点

但实际上你拥有的是
/Classes/*/class\u info/subject
。因此,您有一个节点
Classes
,您希望返回其
class\u info/subject
具有给定值的子节点。在代码中,这是:

DatabaseReference classesRef = FirebaseDatabase.getInstance().getReference("Classes");

Query query = classesRef.orderByChild("class_info/subject").equalTo("Science");

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        list = new ArrayList<>();
        for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
            Class_model new_class = dataSnapshot1.getValue(Class_model.class);
            ...
DatabaseReference classesRef=FirebaseDatabase.getInstance().getReference(“类”);
Query Query=classesRef.orderByChild(“类信息/主题”).equalTo(“科学”);
query.addListenerForSingleValueEvent(新的ValueEventListener()){
@凌驾
public void onDataChange(@NonNull DataSnapshot DataSnapshot){
列表=新的ArrayList();
对于(DataSnapshot dataSnapshot1:DataSnapshot.getChildren()){
Class\u model new\u Class=dataSnapshot1.getValue(Class\u model.Class);
...

输出是什么?从我看到的情况来看,一切都很好。@Ticherhaz当我运行它时,它是空的……没有错误,但它说“考虑添加”“。indexOn:“subject”“at Classes/Class\u info”到您的安全和Firebase数据库规则中以获得更好的性能”你检查过Firebase的安全规则吗?我的规则中没有,因为我不知道如何添加它。我当前的规则是:{“规则”:{.read:“auth!=null”,“.write:”auth!=null”}}^在@Ticherhaz上面