This is my first post so if I didn't follow some protocol I was supposed to, apologies.
I am trying to populate a ListView with some information from my Firebase database. I think the problem I am having is that the query to the database is too slow (the thread is probably downloading pictures) and my activity loads its activity layout without waiting for the thread to finish executing. (If I step through the debugger and wait a bit, I will eventually see the information I am parsing: user names, user numbers, and user pictures) Everything I have queried suggests I should use AsyncTask to accomplish this. As opposed to using thread blocking or a semaphore b/c AsyncTask is thread safe.
To my understanding, Firebase queries are already executing asynchronously; therefore, the doInBackground method for AsyncTask I have "tried" to implement seems redundant. Also, I am a bit confused of AsyncTask's overloaded signature and the call to: new someTask.execute("some stuff in a string").
Any suggestions on how I can accomplish this? Any feedback is very much appreciated!
// Please ignore the minor indentation from pasting my code in
protected void onCreate(Bundle savedInstanceState) {
...
new getFirebaseInfoTask();
}
private class getFirebaseInfoTask extends AsyncTask {
@Override
protected Object doInBackground(Object... args) {
// Do stuff
userInfoList = GetUserInfoFromFirebase.getUserInfo();
// Unsure if I need to return here.
return userInfoList;
}
@Override
protected void onProgressUpdate(Object... args) {
// Update your UI here
populateUserInfoList();
}
}
private void populateUserInfoList() {
// Create list of items
Collections.addAll(userInfoList);
populateFriendsListView();
}
private void populateFriendsListView() {
// Build the adapter
ArrayAdapter<UserInfo> adapter = new MyListAdapter();
// Configure the list view
ListView listView = (ListView) findViewById(R.id.friends_listview);
listView.setAdapter(adapter);
registerClickCallBack();
}
... // More code
public class GetUserInfoFromFirebase {
public static ArrayList getUserInfo() {
final ArrayList<UserInfo> list = new ArrayList<UserInfo>();
Firebase firebase = new Firebase("https:......firebaseio.com");
firebase.child("users").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
HashMap<String, Object> users = (HashMap<String, Object>) snapshot.getValue();
for(Object user : users.values()) {
HashMap<String, Object> userMap = (HashMap<String, Object>) user;
String userNumber = (String) userMap.remove("number");
if(!list.contains(userNumber)) {
String name = (String) userMap.remove("username");
String pic = (String) userMap.remove("profile_picture");
UserInfo info = new UserInfo(userNumber, name, pic);
list.add(info);
}
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {}
});
return list;
}
So I figured it out. I got rid of the AsyncTask and moved the method call I wanted to execute in onProgressUpdate to outside of the for loop of my onDataChange such that the thread that actually gets access to the onDataChange method calls my populateFriendsView method.
private void populateUserInfoList() {
userInfoList = new ArrayList<UserInfo>();
firebase = new Firebase("https://....firebaseio.com");
firebase.child("users").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
HashMap<String, Object> users = (HashMap<String, Object>) snapshot.getValue();
for (Object user : users.values()) {
HashMap<String, Object> userMap = (HashMap<String, Object>) user;
String userNumber = (String) userMap.remove("number");
if (!userInfoList.contains(userNumber)) {
String name = (String) userMap.remove("username");
String pic = (String) userMap.remove("profile_picture");
UserInfo info = new UserInfo(userNumber, name, pic);
userInfoList.add(info);
}
}
// thread executing here can get info from database and make subsequent call
Collections.addAll(userInfoList);
populateFriendsListView();
}
@Override
public void onCancelled(FirebaseError firebaseError) {
String message = "Server error. Refresh page";
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
});
}
Firebase itself provide Asynchronous methods to query data , They have created a sample app to show How to backing up the Listview with firebase information through Android Chat
check this
In that example the core functionality is placed in a generic base adapter called FirebaseListAdapter...
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