I need to store the result of FireBase getValue method that is async by his own. I can\'t use something like \"onPostExecute()\" and, for my purpose, i can\'t execute all my operation \"into onDataChange()\" because i need some references in future time in other activities.
Here my snippet to retrieve data:
List<Village> villages = new LinkedList<>();
Firebase ref = new Firebase(\"MYFIREBASEURL\").child(\"village\");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
spinnerArray.clear();
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Village v = postSnapshot.getValue(Village.class);
villages.add(v);
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println(\"The read failed: \" + firebaseError.getMessage());
}
});
If i try to read villages out of \"onDataChange\" i have, naturally for his async life, null value. There is a way to ensure that onDataChange was called?.
Sorry if it\'s not what you want because my English too bad.
You can define a listener interface to handle it.
Example:
public interface OnGetDataListener {
public void onStart();
public void onSuccess(DataSnapshot data);
public void onFailed(DatabaseError databaseError);
}
And I create a custom function to get data in Database.class:
public void mReadDataOnce(String child, final OnGetDataListener listener) {
listener.onStart();
FirebaseDatabase.getInstance().getReference().child(child).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener.onSuccess(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
listener.onFailed(databaseError);
}
});
}
When I want to get data from Main.class, I do:
private void mCheckInforInServer(String child) {
new Database().mReadDataOnce(child, new OnGetDataListener() {
@Override
public void onStart() {
//DO SOME THING WHEN START GET DATA HERE
}
@Override
public void onSuccess(DataSnapshot data) {
//DO SOME THING WHEN GET DATA SUCCESS HERE
}
@Override
public void onFailed(DatabaseError databaseError) {
//DO SOME THING WHEN GET DATA FAILED HERE
}
});
}
By this way, you can reuse your method and handle data.
Just to add to Manh\'s answer, one would call onStart()
just before
FirebaseDatabase.getInstance().getReference().child(child).addListenerForSingleValueEvent(new ValueEventListener() {
And in onStart()
, typically you would show a progressDialog:
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(getContext());
mProgressDialog.setMessage(getString(R.string.loading));
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
And in onSuccess()
dismiss the dialog and load the data onto GUI (or whatever you want to do)
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
What I understood is you are trying to save the snapshot data into a variable but due to async task the variable turns out to be null, this is because of the nature of async task, what you could do is pass the snapshot data from firebase listener function to your custom function outside and store the snapshot data into a global variable.Then you can use the variable as like you want to.