0

I am new in this ! Please can someone help me. I know that here I am dealing with asynchronous programming, I am trying to return the String but it still returning null.

Can someone tell me where I am wrong.

public interface OnGetDataListener {
    public void onStart();
    public void onSuccess(DataSnapshot data);
    public void onFailed(DatabaseError databaseError);
}

public void mReadDataOnce(String email ,String child, final OnGetDataListener listener) {
    listener.onStart();
    myRef.child(email).child(child).limitToFirst(1).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            listener.onSuccess(dataSnapshot);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            listener.onFailed(databaseError);
        }
    });
}

private String mCheckInforInServer(String email ,String child) {
    final String[] returnvalue = new String[1];

    mReadDataOnce(email ,child, new OnGetDataListener() {

        @Override
        public void onStart() {
            //DO SOME THING WHEN START GET DATA HERE
        }

        @Override
        public void onSuccess(DataSnapshot data) {
            returnvalue[0] = data.getValue().toString();
            //DO SOME THING WHEN GET DATA SUCCESS HERE
        }

        @Override
        public void onFailed(DatabaseError databaseError) {
            //DO SOME THING WHEN GET DATA FAILED HERE
        }
    });

    return returnvalue[0] ;
}

Then I am calling it:

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

    Log.i(" ","HIMANSHU" +  mCheckInforInServer("a","name"));
    Log.i(" ","HIMANSHU" +  mCheckInforInServer("a","email"));
}

Log is printing null, I want the values. Please help!

K.Os
  • 5,123
  • 8
  • 40
  • 95
  • Please see my answer here where you can use the value from datasnapshot outside onDataChange https://stackoverflow.com/a/55741593/3904109 – DragonFire Apr 18 '19 at 08:16

1 Answers1

1

Take a minute, try to read your code and understand it.

Inside the method mCheckInforInServer() the code gets executed in following sequence :

  1. initialize returnvalue
  2. create a anonymous instance of type OnGetDataListener.
  3. pass this instance of type OnGetDataListener to mReadDataOnce() method and let this method use OnGetDataListener instance to change the value of returnvalue whenever it wants (which will take some time to complete since its using network with some latencies. This latency will be greater than the latency in execution of next 2 statements almost in 99.9999% cases)
  4. since mReadDataOnce() operates asynchronously, the program control lets it go on and continue with the implementation of mCheckInfoInServer()
  5. return the current value of, which in 0.0001% case will be the value that you need.

So, you just need to get to that 0.0001% case.

Or, you can ask your mReadDataOnce() to invoke a method inside your main-activity when it completes, which will be give you the value that you need in 99.9999% cases, if all goes well. You can try somthing like this :

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

    mReadDataOnce("a" ,"email", new OnGetDataListener() {

        @Override
        public void onStart() {
            //DO SOME THING WHEN START GET DATA HERE
        }

        @Override
        public void onSuccess(DataSnapshot data) {
            Log.i("", "HIMANSHU" +  data.getValue().toString());
            //DO SOME THING WHEN GET DATA SUCCESS HERE
        }

        @Override
        public void onFailed(DatabaseError databaseError) {
            //DO SOME THING WHEN GET DATA FAILED HERE
        }
    });
    mReadDataOnce("a" ,"email", new OnGetDataListener() {

        @Override
        public void onStart() {
            //DO SOME THING WHEN START GET DATA HERE
        }

        @Override
        public void onSuccess(DataSnapshot data) {
             Log.i("", "HIMANSHU" +  data.getValue().toString());            
             //DO SOME THING WHEN GET DATA SUCCESS HERE
        }

        @Override
        public void onFailed(DatabaseError databaseError) {
            //DO SOME THING WHEN GET DATA FAILED HERE
        }
    });
}

Update in the code:

Actually, here I am trying to store value from the database to the Records Class.

public interface OnGetDataListener {
    public void onStart();
    public void onSuccess(DataSnapshot data);
    public void onFailed(DatabaseError databaseError);
}

public void mReadDataOnce(String email ,String child, final OnGetDataListener listener) {
    listener.onStart();
    myRef.child(email).child(child).limitToFirst(1).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            listener.onSuccess(dataSnapshot);
            record.setName(dataSnapshot.getValue().toString());
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            listener.onFailed(databaseError);
        }
    });
}

And then retrieving the value from the Records class in onCreate()

mReadDataOnce("a" ,"email", new OnGetDataListener() {

        @Override
        public void onStart() {
            //DO SOME THING WHEN START GET DATA HERE
        }

        @Override
        public void onSuccess(DataSnapshot data) {
            Log.i("", "HIMANSHU" +  data.getValue().toString());
            record.setName(data.getValue().toString());
            //DO SOME THING WHEN GET DATA SUCCESS HERE
        }

        @Override
        public void onFailed(DatabaseError databaseError) {
            //DO SOME THING WHEN GET DATA FAILED HERE
        }
    });

    Log.i(" ","HIMANSHUKUSHWAHA"+record.getName());
    //Printing null
zeekhuge
  • 1,594
  • 1
  • 13
  • 23
  • Thanks for your reply. But I am trying to access the returned value outside the mReadDataOnce() method in onCreate(). – Praveen Kushwaha Oct 10 '17 at 20:57
  • so for example, you want to use that data in a method called `doSomethin()` inside the main-activtiy. Then, you can simply call `doSomething(data)` inside implementation of `OnGetDataListener#onSuccess()` – zeekhuge Oct 10 '17 at 21:01
  • Did you really read my answer ? and the code that I have added in the ans ? – zeekhuge Oct 11 '17 at 06:25