I am working on an app for a hotel, which enables hotel management to report and view concerns and issues. I am using Android and Firebase for this app.
Here is the database structure of a reported concern:
To minimize data download and optimize speed, I am adding "Active" and "Resolved" nodes in the database, like below:
Now, the hotel wants me to add the function to create an Excel report of concerns closed/resolved within the past month. For this, I will be attaching a Single Value Event Listener on the "resolved" node, get keys of resolved concerns, then for each key, fetch data from "allConcerns" node, store each node's data into an ArrayList of String. After which I will use this JSON to Excel API for Android to create Excel file.
I am able to access keys of resolved concerns with this code:
DatabaseReference resolvedReference = FirebaseDatabase.getInstance().getReference()
.child(getApplicationContext().getResources().getString(R.string.concerns))
.child(getApplicationContext().getResources().getString(R.string.resolved));
final ArrayList<String> keys = new ArrayList<>();
resolvedReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
//Getting keys of all resolved concerns in keys arraylist here
for (DataSnapshot ds : snapshot.getChildren()){
keys.add(ds.getValue(String.class));
}
//Storing JSON data in this arraylist
final ArrayList<String> data = new ArrayList<>();
for(int i = 0; i<keys.size() ; ++i){
String key = keys.get(i);
//Getting data of each concern here
FirebaseDatabase.getInstance().getReference().child(getApplicationContext().getResources().getString(R.string.allConcerns))
.child(key).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
String type = snapshot.child("type").getValue().toString();
Log.i("Type", type);
if(type.equals("0")) {
SafetyConcernClass s = snapshot.getValue(SafetyConcernClass.class);
Log.i("Snapshot of key", s.toString());
data.add(s.toString());
}
else{
GembaWalkClass g = snapshot.getValue(GembaWalkClass.class);
Log.i("Snapshot of key", g.toString());
data.add(g.toString());
}
Proof proof = snapshot.child("proof").getValue(Proof.class);
Log.i("Proof", proof.toString());
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
//Issue I am facing is here
Log.i("Data size", String.valueOf(data.size()));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
The real issue here is while logging data.size(). Since Firebase is asynchronous, FOR loop ends before data is fetched and entered into the data ArrayList, hence it gives me a size of 0. And since no data is fetched, I can't create an Excel file.
My question is, how can I make sure I am proceeding to log data.size() ONLY after data of respective resolved concerns is stored in the ArrayList?