I'm trying to get data like SQL left join clause. Here are my nodes sample:
Firebase Database
{
"teachers": {
"nodeKey01": {
"name":"captain hook",
"branch":"Math",
},
"nodeKey02": {
"name":"peter pan",
"branch":"Science",
}
},
"students": {
"nodeKey100": {
"name" : "davy jones",
"teacherKey": "nodeKey01"
},
"nodeKey101": {
"name" : "jack sparrow",
"teacherKey": "nodeKey02"
},
"nodeKey102": {
"name" : "salazar",
"teacherKey": "nodeKey01"
}
}
}
I'd like to query "students" referances and get datas with "teachers" name and branch. I loked documantation and many examples bu didn't figure out. Firebase is not include SQL database languge but there has to be a way/method to join nodes.
Models:
public class Student {
private String name;
private String teacherKey;
private String key;
private Teacher teacher;
public Student() {}
@Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put(name, name);
result.put(teacherKey, teacherKey);
return result;
}
public String getKey() { return key;}
public void setKey(String objectKey) { this.key = key; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getTeacherKey() { return teacherKey; }
public void setTeacherKey(String teacherKey) { this.teacherKey = teacherKey; }
public Teacher getTeacher() { return teacher; }
public void setTeacher(Teacher teacher) { this.teacher = teacher; }
}
public class Teacher {
private String name;
private String branch;
private String key;
public Teacher() {}
@Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put(name, name);
result.put(branch, branch);
return result;
}
public String getKey() { return key;}
public void setKey(String objectKey) { this.key = key; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBranch() { return branch; }
public void setBranch(String branch) { this.branch = branch; }
}
Firebase Query Codes:
public class StudentsFragment extends Fragment {
List<Students> listData = new ArrayList<>();
StudentAdapter adapter;
@BindView(R.id.list) ListView _list;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_students, container, false);
ButterKnife.bind(this, view);
mDatabase = FirebaseDatabase.getInstance().getReference();
adapter = new StudentAdapter(getActivity(), listData);
_list.setAdapter(adapter);
initDatabase();
return view;
}
private void initDatabase() {
final List<Teacher> teachers = new ArrayList<>();
Query query1 = mDatabase.child("teachers");
query1.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
teachers.clear();
for(DataSnapshot data : dataSnapshot.getChildren()){
Teacher item = data.getValue(Teacher.class);
item.setKey(data.getKey());
teachers.add(item);
}
Query query2 = mDatabase.child("students");
query2.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listData.clear();
for (DataSnapshot data: dataSnapshot.getChildren()) {
AbsentTeacher item = data.getValue(Student.class);
item.setKey(data.getKey());
item.setTeacher(getTeacherByKey(teachers, item.getTeacherKey()));
listData.add(item);
}
adapter.notifyDataSetChanged();
}
private Teacher getTeacherByKey(List<Teacher> list, String key) {
int index = 0;
for (int i=0;i<list.size();i++){
if (list.get(i).getObjectKey().equals(key)) {
index = i;
break;
}
}
return list.get(index);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
}
It's working but I'm getting joined nodes with two firebase query and "for loop"... And this seems a performance problem.