Praveen Kushwaha
Praveen Kushwaha

Reputation: 13

Trying to use data outside the onDataChange() in Firebase

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!

Upvotes: 0

Views: 1104

Answers (1)

zeekhuge
zeekhuge

Reputation: 1594

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

Upvotes: 1

Related Questions