0

My log can print all Exercise object. But listExercise is null when I call. What's the problem?

ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                Exercise exercise = postSnapshot.getValue(Exercise.class);
                String temp = exercise.toString();
                Log.d("exercise: ", temp + "\n"); // can log all
                listExercises.add(exercise);
            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            Log.d("The read failed: ", firebaseError.getMessage());
        }
    });
Log.d("LISTSIZE: ", String.valueOf(listExercises.size())); // return 0

[UPDATE] The answer for anyone need:

@Override
        public void onDataChange(DataSnapshot snapshot) {
            for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                Exercise exercise = postSnapshot.getValue(Exercise.class);
                listExercises.add(exercise);
            }
            // action with data here
            Exercise ex = listExercises.get(0);
            tvQuestion.setText(ex.getQuestion);
        }
kidsoul
  • 69
  • 1
  • 10
  • Are you getting some error stack trace? – jDur Apr 18 '16 at 08:51
  • No, It just return an empty list when I logged: Log.d("LISTSIZE: ", String.valueOf(listExercises.size())); – kidsoul Apr 18 '16 at 08:53
  • Probably you are checking the list before Exercise has been inserted. Notice this works asynchronously. Put the Log of "LISTSIZE" after listExercises.add(exercise); – jDur Apr 18 '16 at 09:02
  • Of course, I put Log of "LISTSIZE" after listExercises.add(exercise); I will edit my question for more detail. – kidsoul Apr 18 '16 at 09:06
  • Is your listExcercise a custom implementation of List or is class Exercise doing something in the method toString(); Maybe if you put the rest of the code I can help you better :) – jDur Apr 18 '16 at 09:09
  • Ok, I've just seen your editted question. Put the Log just after the for .. for { .. } Log.d("LISTSIZE": ..) }. I mean inside onDataChange method – jDur Apr 18 '16 at 09:11
  • Did you initialize **listExercises**? Make sure it and then make a look if you are getting correctly your JSON from Firebase – M. Mariscal Apr 18 '16 at 09:12
  • @M.Mariscal: Of course, List listExercises = new ArrayList(); – kidsoul Apr 18 '16 at 09:18
  • @jDur: It can print to size of list, sir. But I want it out of for loop. Need I assign listExercises to another list after loop? – kidsoul Apr 18 '16 at 09:20
  • Have in mind that what happens inside the callback (the onDataChange method) is the result of other thread, and you don't know when the list will be filled (because it is asynchronous). The list is filled in some moment, you must notify the flow of your App when this occurs. For example calling a method after the loop: for { ... } Log.d("LISTSIZE"..); doSomething(theList); – jDur Apr 18 '16 at 09:41

3 Answers3

3

When the method "paintListInScreen" is called, you know for sure the list have some content (or maybe not, that depends on the server, but you are being consistent with threads).

ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot snapshot) {
        for (DataSnapshot postSnapshot : snapshot.getChildren()) {
            Exercise exercise = postSnapshot.getValue(Exercise.class);
            String temp = exercise.toString();
            Log.d("exercise: ", temp + "\n"); // can log all
            listExercises.add(exercise);
        }
         Log.d("LISTSIZE: ", String.valueOf(listExercises.size())); // return 0
        paintListInScreen(listExercises);
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {
        Log.d("The read failed: ", firebaseError.getMessage());
    }
});
jDur
  • 1,481
  • 9
  • 10
  • Thanks I will try it – kidsoul Apr 18 '16 at 16:03
  • You are correct, jDur. After I tried, I found it two point for we can use data I get: The first, it's time after onDataChange method. The second, when you do some action after sync data, maybe it's onClick of button...etc.. – kidsoul Apr 19 '16 at 06:05
  • Your welcome :). If you think this is a correct answer please mark it as correct so other users could find it helpful. – jDur Apr 19 '16 at 11:00
0

For Java 8 and newer versons (For Android API Level 24 is required ):

int size = dataSnapshot.getChildren().spliterator().getExactSizeIfKnown() ;

For Older Versions:

int size = 0 
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
    size++ ;
}
Saurabh Padwekar
  • 3,888
  • 1
  • 31
  • 37
0

To get the size of datasnapshot object:

dataSnapshot.getChildrenCount();
Zain
  • 37,492
  • 7
  • 60
  • 84