0

My code retrieves boolean values from a Firebase realtime database. However, those values automatically delete themselves for no apparent reason. I cannot see why this is happening and am going insane.

The code should work like so: create view, download booleans if they exist, done.

This is what seems to be happening: create view, download booleans if they exist, erase them, done.

Here is my code:

public class ACdayFragment extends Fragment {

//TAG
private static final String TAG = "ACdayFragment";

//Context
private Context context;

//Days for Booleans
Boolean Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;

//Firebase Stuff
FirebaseMethods firebaseMethods;
DatabaseReference userDatabase;
DatabaseReference availDatabase;
FirebaseAuth mAuth;

//Strings
String key = mAuth.getInstance().getUid();

//TreeMap
TreeMap<Integer, Boolean> dayMap = new TreeMap<>();


@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_ac, container, false);

    mAuth = FirebaseAuth.getInstance();
    key = FirebaseAuth.getInstance().getUid();
    userDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(key);
    availDatabase = userDatabase.child("Days");


    //This method should populate my dayMap treemap
    getData();

    //But when I retrieve it here, it appears empty
    Log.e(TAG, "getData0: "+ dayMap);



    return view;
}

private void getData() {
    FirebaseUser user = mAuth.getCurrentUser();

    if (user != null) {
        availDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (getActivity() == null) {
                    return;
                }
                if (dataSnapshot.exists() && dataSnapshot.getChildrenCount()>0) {
                    Map<String, Boolean> map = (Map<String, Boolean>) dataSnapshot.getValue();

                    if (map.get("sunday")!= null) {
                        dayMap.put(0, true);
                    }
                    if (map.get("monday")!= null) {
                        dayMap.put(1, true);
                    }
                    if (map.get("tuesday")!= null) {
                        dayMap.put(2, true);
                    }if (map.get("wednesday")!= null) {
                        dayMap.put(3, true);
                    }if (map.get("thursday")!= null) {
                        dayMap.put(4, true);
                    }if (map.get("friday")!= null) {
                        dayMap.put(5, true);
                    }if (map.get("saturday")!= null) {
                        dayMap.put(6, true);
                    }


                    //This log does show me a populated dayMap
                    Log.e(TAG, "getData1: "+ dayMap );
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }
    Log.d(TAG, "getData2: " + dayMap );
}
@Override
public void onStart() {
    super.onStart();
}
@Override
public void onStop() {
    super.onStop();
}
}
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Check **[this](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774)** out. – Alex Mamo May 20 '19 at 11:37

1 Answers1

1

Basically you need to understand what happens between the following 2 lines of code:

getData(); //Fire and Forget
//...
//The getData() method has requested data from Firebase but it takes sometime to return the data
//Meanwhile, this method execution doesn't wait for Firebase and hence the dayMap in the next line is not filled yet!
//...
Log.e(TAG, "getData0: "+ dayMap); //Does not wait for Firebase to return the data

The getData() method just creates and adds an object of ValueEventListener which contains the onDataChange method, this method is called for the first time when Firebase completes fetching the data. Note that it will also be called everytime the data is updated. Please refer the documentation of ValueEventListener

I suggest you first understand Synchronous and Asynchronous execution. Also, you must learn about listeners and callbacks.

P.S: @NewAppDeveloping Don't hate yourself. Just learn from the basics.

UPDATE:

The simplest way for you to fix this is to do something with your boolean tree map by updating the onDataChange method as shown below:

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    if (getActivity() == null) {
        return;
    }
    ....
    ....//Your existing code: Get the booleans and create the treemap
    ....
    //This log does show me a populated dayMap
    Log.e(TAG, "getData1: "+ dayMap );

    ....//Do what you intend to here like filling the view/ updating the view, etc.
}

The onCreateView must return a view and if you are waiting for the data from Firebase here it is not right. You must return the empty view then fill it after the data is received as mentioned above.

Nabster
  • 1,187
  • 2
  • 10
  • 27
  • So adding an interface and implementing a listener would help? It's what I understood from reading the links. and sorry, I spent the whole week trying to fix it and got overwhelmed – NewAppDeveloping May 17 '19 at 06:01
  • Apologies for the late response. Updated the answer. – Nabster May 27 '19 at 03:29