Trying to use data outside the onDataChange() in Firebase

我的梦境 提交于 2019-12-25 00:37:14

问题


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!


回答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


来源:https://stackoverflow.com/questions/46675057/trying-to-use-data-outside-the-ondatachange-in-firebase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!