0

I'm trying to get name data from Firebase using uid from another collection with an interface, set that data into a variable, and do some task. Then let's say I want to show a Toast if the task is done or not.

This is the method

public void createExcel(final String grade) {
    Boolean taskSuccess;
    DatabaseReference attendanceRef = FirebaseDatabase.getInstance().getReference().child("attendance").child(grade);
    attendanceRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            String thisUid;
            for (DataSnapshot ds : snapshot.getChildren()) {
                    for (DataSnapshot ds2 : ds.getChildren()) {
                    thisUid = ds2.child("uid").getValue().toString();
                    readData(thisUid, new MyCallBack() {
                        @Override
                        public void onCallback(String value) {
                            thisName[0] = value;
                            //Do some task
                            if (//task success) {
                                taskSuccess == true;
                            }
                        }
                    });
                }
            }
            System.out.println(taskSuccess); //taskSuccess value is always false
         }
    });
}

This is my interface

public interface MyCallBack {
    void onCallback (String value);
}

This is my readData method

public void readData (String uid, final MyCallBack myCallBack) {
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users").child(uid);
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            String value = snapshot.child("name").getValue().toString();
            myCallBack.onCallback(value);
        }

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

        }
    });
}

Is there any way I can set that taskSuccess value inside onDataChange method and use it outside onDataChange method? Because if I make a Toast inside readData it will make some Toasts because of the loop to get the data from database

Josh Adrian
  • 126
  • 1
  • 9
  • Probably because your `readData` doesn't actually read - it listens to changes in `users` document, and I can only assume that `users` don't change all that frequently. – M. Prokhorov Aug 17 '20 at 11:28
  • Have you tried to move `System.out.println(thisName[0]);` inside `onCallback()` method? Please respond with @AlexMamo – Alex Mamo Aug 17 '20 at 11:44
  • @AlexMamo Yes, thankyou I've tried that, and now I know how things work on my code, and I have another problem. I've editted my question – Josh Adrian Aug 17 '20 at 11:51
  • Your `onCallback` method is still asynchronous, You cannot simply use `taskSuccess` the outside that method. Check **[this](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774)** out. – Alex Mamo Aug 17 '20 at 12:04
  • @AlexMamo I know your video, the thing is I want to know if there's another way around to let me call `taskSuccess` outside that method. – Josh Adrian Aug 17 '20 at 13:05
  • No, there is not. You cannot force an asynchronous operation to be synchronous. – Alex Mamo Aug 17 '20 at 14:21
  • 1
    Okay @AlexMamo I guess I need to rework me code to make it works. Thank you so much – Josh Adrian Aug 17 '20 at 15:13

0 Answers0