0

In the addValueEventListener I am getting data for firebase database correctly. I copy that data to a variable called newDay. However, once I am out of the addValueEventListener, the data is gone. How do I make sure the data stays?

        mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
        String current_uid = mCurrentUser.getUid();
        mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(current_uid).child("week").child(day);
        newDay = new ArrayList<Integer>();
        mUserDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                newDay.addAll((ArrayList<Integer>)dataSnapshot.getValue());
                Log.d("newday", "onDataChange:"+newDay.toString());

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
        Log.d("after","value " +newDay.toString());

These are the log results:

03-04 00:01:28.475 7961-7961/com.example.fake9.tendee D/newday: onDataChange:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

In after, newDay is strangely empty.

03-04 00:04:54.665 9906-9906/com.example.fake9.tendee D/after: value []

Entire code provided if details are not enough. Many parts are irrelevant it seems:

public class ScheduleActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {

    private Toolbar mToolbar;
    private Spinner chooseDay;
    private TimePicker startTime;
    private TimePicker endTime;
    private Button busyBtn;
    private Button freeBtn;
    String day;
    Map<String,ArrayList<Integer>> changeweek;
    ArrayList<Integer> test;
    ArrayList<Integer> newDay;

    private DatabaseReference mUserDatabase;
    private FirebaseUser mCurrentUser;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_schedule);

        mToolbar = (Toolbar)findViewById(R.id.schedule_toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Schedule");

        chooseDay = (Spinner)findViewById(R.id.chooseDay_spinner);
        chooseDay.setOnItemSelectedListener(this);
        List<String> week = new ArrayList<String>();
        week.add("Monday");
        week.add("Tuesday");
        week.add("Wednesday");
        week.add("Thursday");
        week.add("Friday");
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,week);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        chooseDay.setAdapter(dataAdapter);

        startTime = (TimePicker)findViewById(R.id.start_timePicker);
        endTime = (TimePicker)findViewById(R.id.end_timePicker);
        freeBtn = (Button)findViewById(R.id.free_btn);
        freeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int startHour = startTime.getCurrentHour();
                int startMin = startTime.getCurrentMinute();
                int endHour = endTime.getCurrentHour();
                int endMin = endTime.getCurrentMinute();
                int startIndex = 0;
                int endIndex = 0;
                int intervals = 0;
                //Log.d("hour", "onClick: "+startHour);
                //Log.d("minute", "onClick: "+startMin);
                if (startHour < 9 || startHour > 17 || endHour < 9 || endHour > 17) {
                    Toast.makeText(ScheduleActivity.this, "invalid time", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (startHour > endHour) {
                    Toast.makeText(ScheduleActivity.this, "impossible time", Toast.LENGTH_SHORT).show();
                    return;
                }
                startIndex = (startHour - 9) * 2;
                if (startMin >= 30) {
                    startIndex = startIndex + 1;
                }
                //Log.d("startIndex", "onClick: "+startIndex);
                endIndex = (endHour - 9) * 2;
                if (endMin >= 30) {
                    endIndex = endIndex + 1;
                }
                final int finalstart = startIndex;
                final int finalend = endIndex;
                //Log.d("endIndex", "onClick: "+endIndex);
                mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
                String current_uid = mCurrentUser.getUid();
                mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(current_uid).child("week").child(day);
                newDay = new ArrayList<Integer>();
                mUserDatabase.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        newDay.addAll((ArrayList<Integer>)dataSnapshot.getValue());
                        Log.d("newday", "onDataChange:"+newDay.toString());

                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
                Log.d("after","value " +newDay.toString());
                intervals = endIndex - startIndex;
                for (int i = startIndex; i < endIndex; i++) {
                    Log.d("indexes", "onClick: "+i);
                }
            }
        });
    }
  • paste the complete code – Nouman Ch Mar 04 '18 at 05:24
  • Possible duplicate of [How to return dataSnapshot value as a result of a method?](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method) – Alex Mamo Mar 04 '18 at 10:18

1 Answers1

1

The line

Log.d("after","valu" + newDay.toString());

is calling before firebase gets result from database. All you need to do is create a method

public void printResult(){
  Log.d("after","valu" + newDay.toString());
}

Now call this method as

newDay = new ArrayList<Integer>();
        mUserDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {


newDay.addAll((ArrayList<Integer>)dataSnapshot.getValue());
                Log.d("newday", "onDataChange:"+newDay.toString());
                printResult();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Reason

Firebase has it's own async mechanism like volley library onDataChange function will be call when firebase gets some result from internet and execute the below code as normally in your case below code is your Log.d("after","value"+newDay.toString()); line.

Hope this will help you.

Nouman Ch
  • 4,023
  • 4
  • 29
  • 42