Issue
I am trying to wrap a Service around a (Firebase query)x(Perform some action) functionality. Namely, I would need to retrieve data from Firebase and then, for each item retrieved, perform a certain download-a-file-like action (which is itself can be an AsyncTask or a Service). I have a handler inside my service:
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).child("oj_goals");
ref.orderByChild("ojTag").addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
OjGoal goal= dataSnapshot.getValue(OjGoal.class);
Log.d("inside onChildAdded",goal.getMe());
data.add(goal);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
//FIXME: the below code continues to execute even if the Firebase-call has not yet completed
//
Intent intent= new Intent("com.example.sj.keymeasures.BAR_CHART_DATA_PREPARATION_FINISHED");
/**
* https://stackoverflow.com/questions/43800772/does-variable-order-matter-while-parcel-read-write-operation-in-parcelable
*/
intent.putParcelableArrayListExtra("oj_goals",data);
Log.d("[Handler]","sendingBroadcast with size "+data.size());
sendBroadcast(intent);
stopSelf(msg.arg1);
}
Now as you can see in the FIXME in the code, what I receive on the other end -- inside the dedicated receiver -- is an empty list. By now I know this whole thing was a bad idea, but how would you design what I am trying to accomplish (see first paragraph), without weird stuff like nested async-tasks?
Solution
It's pretty straightforward: the code that needs to execute after the child node was loaded, should be inside the onChildAdded
function:
public void handleMessage(Message msg) {
super.handleMessage(msg);
FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).child("oj_goals");
ref.orderByChild("ojTag").addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
OjGoal goal= dataSnapshot.getValue(OjGoal.class);
Log.d("inside onChildAdded",goal.getMe());
data.add(goal);
Intent intent= new Intent("com.example.sj.keymeasures.BAR_CHART_DATA_PREPARATION_FINISHED");
intent.putParcelableArrayListExtra("oj_goals",data);
Log.d("[Handler]","sendingBroadcast with size "+data.size());
sendBroadcast(intent);
stopSelf(msg.arg1);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
}
Answered By - Frank van Puffelen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.