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?.
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With