1

I am using firebase geofire library to fetch key's based on location but because of thousands of keys are returned in onKeyEntered() event every time I have to take the key refer firebase and get the object back and set it to listview becoming very slow. I tried commenting all other work in onKeyEntered() to see how fast geofire is then I was surprised withing 900 milli's all callbacks received.

So now what is the best optimized way to get the data from firebase using the key passed in onKeyEntered() callback and set it to listview so that even for thousands of entries listview should load fast

I thought of AsyncTask in every callback give the fetching data work to AsyncTask and proceed with next callback key and do same, but not sure thats correct.

Or load only few and then load as scroll's is also good idea but geofire returns keys from all over the database so there is no option to get only few latest one so not sure how to implement it.

This is what I am trying but list view loads very slow.

  @Override
public void onKeyEntered(String key, GeoLocation location) {
    Log.d("geoevent", key);
    mDatabaseTemp = FirebaseDatabase.getInstance().getReference("/posts/" + key);
    mDatabaseTemp.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Post post = new Post();
            post = dataSnapshot.getValue(Post.class);
            mPosts.add(post);
            mPostAdapter.notifyDataSetChanged();
            mRecycler.smoothScrollToPosition(mPosts.size() - 1);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(getActivity(), "error" + databaseError, Toast.LENGTH_LONG).show();

        }
    });
}
Shivaraj Patil
  • 8,186
  • 4
  • 29
  • 56
  • I wrote a few hints below, but in general this question is too broad. Please limit to a single question, e.g. "why are the items coming back faster than I expected?" (which is because [the requests are pipelined](http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786) btw). – Frank van Puffelen Jul 21 '16 at 14:51

1 Answers1

1

Question of the type "how to best" are notoriously difficult to answer. But I'll give a few hints about the general behavior of the system that you may not be aware of.

  1. the Firebase Database client interacts with the network and disk on a separate thread. When data is available for your client, it calls your handlers on the main/UI thread. This means that putting your calls in an AsyncTask is only useful if you'll be doing significant work in the callback.
  2. the Firebase Database client pipelines the calls to the server over a single connection. To read more about why that affects performance, see Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly.
  3. loading thousands of items into a mobile device over the network is in general not a good idea. You should only load data that you'll show to the user and thousands of items is well beyond what can be reasonably presented on a mobile screen. When developing a location based app, you could show a map where the user indicates a hotspot and you use Geoqueries to only request items around that spot.
Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • In geofire library I liked the fact that it fetches all keys instantly but generally every one needs a callback for when it finishes fetching data for a particular location. – Shivaraj Patil Jul 21 '16 at 19:24
  • On your 3rd point I want to show few posts which are recent but geofire library gives callback for all the items stored for x location. So if thousands of posts available for x location then it gives callback for all starting from first stored entry so to show only recently added posts I have to go through all the callbacks, use key to refer firebase and fetch data, compare post time and filter accordingly which will actually take same time as showing all items, It will be helpful if you can provide any recommended way of doing this. Thanks in advance – Shivaraj Patil Jul 21 '16 at 19:32
  • If you only want to get items that are recent, how about keeping a separate geo-node for recent items? That will prevent the need for client-side filtering, which will drastically reduce your user's bandwidth usage. – Frank van Puffelen Jul 21 '16 at 22:01
  • ya nice idea but in this case recent posts are dynamic in the sense recent posts depends on users current location so separate node might not work, we never know which post is recent to which location so cannot create separate node for each location. Please help me. – Shivaraj Patil Jul 22 '16 at 06:38
  • Is there any way I can make a single firebase call and pass list of keys and get list of objects back? or in geofire any way to filter based on the item stored time at geofire node? so that I can remove updates after first 10 calls which are recently stored keys. – Shivaraj Patil Jul 22 '16 at 06:55