0

Success retrieve data in onDataChange method. However, cant retrieve data outside onDataChange method (inside onCreateView). While trying to get data from trackList, it return null.

Below is how i retreive data from firebase and try to display on the view.

currentUser = (User) getArguments().getSerializable("currentUserBundle");

    databaseTracks = FirebaseDatabase.getInstance().getReference("tracks").child(currentUser.getUserId());
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yy");
    Date date = new Date();
    todayDate = simpleDateFormat.format(date);

    databaseTracks.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Iterable<DataSnapshot> children = dataSnapshot.getChildren();

            if (trackList != null) {
                trackList.clear();
            }

            for (DataSnapshot c : children) {
                trackList.add(c.getValue(UserFoodRecord.class));
            }

        }

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

        }
    });

    if (trackList != null) {
        for (UserFoodRecord u : trackList) {
            //Problem at here !!!!!!
            //return null while try to retrieve data
            dateList.add(u.getDate());
            if (u.getDate() == todayDate) {
                checkTodayRecord = true; //got today record
                UserFoodRecord tempRecord = new UserFoodRecord(u.getDate(), u.getBreakfast(), u.getLunch(), u.getDinner(), u.getOther()
                        , u.getExercise(), u.getGoal(), u.getFood(), u.getExerciseBurn());
                currentUserFoodRecord = tempRecord;
            }
        }
    }

    //return null
    if (currentUserFoodRecord != null) {
        caloriesGoal.setText(currentUserFoodRecord.getGoal().toString());
        caloriesFood.setText(currentUserFoodRecord.getFood().toString());
        caloriesExerc.setText(currentUserFoodRecord.getExerciseBurn().toString());
        caloriesRemain.setText(currentUserFoodRecord.getRemaining().toString());
    }

Data from firebase

enter image description here

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
CJ Yeo
  • 51
  • 1
  • 7
  • I recommend you see the last part of my anwser from this **[post](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774)** and also take a look at this **[video](https://www.youtube.com/watch?v=OvDZVV5CbQg)** to better understand why you have this behaviour. – Alex Mamo Jul 20 '18 at 17:47

1 Answers1

1

Move your code inside onDataChange as Firebase fetches data asynchronously

databaseTracks.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Iterable<DataSnapshot> children = dataSnapshot.getChildren();

            if (trackList != null) {
                trackList.clear();
            }

            for (DataSnapshot c : children) {
                trackList.add(c.getValue(UserFoodRecord.class));
            }

            if (trackList != null) {
                for (UserFoodRecord u : trackList) {
                    dateList.add(u.getDate());
                    if (u.getDate() == todayDate) {
                        checkTodayRecord = true; //got today record
                        UserFoodRecord tempRecord = new UserFoodRecord(u.getDate(), u.getBreakfast(), u.getLunch(), u.getDinner(), u.getOther()
                                , u.getExercise(), u.getGoal(), u.getFood(), u.getExerciseBurn());
                        currentUserFoodRecord = tempRecord;
                    }
                }
            }


            if (currentUserFoodRecord != null) {
                caloriesGoal.setText(currentUserFoodRecord.getGoal().toString());
                caloriesFood.setText(currentUserFoodRecord.getFood().toString());
                caloriesExerc.setText(currentUserFoodRecord.getExerciseBurn().toString());
                caloriesRemain.setText(currentUserFoodRecord.getRemaining().toString());
            }

        }

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

        }
    });
prashant17
  • 1,520
  • 3
  • 14
  • 23
  • i have tried this before, but when i tried to display tempRecord data it become null again when outside onDataChanged() – CJ Yeo Jul 20 '18 at 10:46
  • 1
    its because your `display tempRecord` code is executed before `onDataChange` is called as Firebase fetches data `asynchronously` – prashant17 Jul 20 '18 at 10:55
  • Still having problem when i try to display data. 07-20 18:59:43.072 15830-15830/com.example.cheejin.fyp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.cheejin.fyp, PID: 15830 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Double com.example.cheejin.fyp.UserFoodRecord.getGoal()' on a null object reference at com.example.cheejin.fyp.AddFragment$2.onClick(AddFragment.java:164) – CJ Yeo Jul 20 '18 at 11:01
  • post line of code where you are getting NullPointerException. `UserFoodRecord.getGoal() must be NULL` – prashant17 Jul 20 '18 at 11:08
  • Now i able to get the data as long as i do all my method inside onDataChanged() method. Thanks for helping. – CJ Yeo Jul 21 '18 at 07:56