Posted on

Android Firebase RecyclerView With Geofire


Android Firebase RecyclerView With Geofire

Designed by Freepik

Hey guy, there’s two ways to fetch data from Firebase. First – ¬†listen to node which is the list of items you want to display. You get the whole list in data snapshot and you just display it or you listen for children changes. Second is to fetch different node keys and listen to them. In particular, that’s what happens when you use Geofire. You just get ids and from that point have to fetch one by one. That’s what we’re going to talk about today.

 

Fetch Key For Location

For Geofire you create a separate node, it stores locations for your keys. So to get a list of user ids near you query Geofire and build a list of ids. Then for each we set listener.

onKeyEntered called during initial fetching each time, then when fetched all data, onGeoQueryReady is called. So we build list of ids and then set value listeners for each user. When new key is added to the location near you onKeyEntered is called. So using fetchedUserIds flag we wait till fetched all initial users. Why wait and not set listener right away like we do if it’s new user after fetching in the onKeyEntered callback? We need to know initial list size in the userValue callback. And for optimization purposes.

Set User Value Listener

What we got above is list of user id so we can set listeners for each with paths like this ‘users/id’. And here comes the use of initialListSize. Sure, we can just set value listeners for each user, and in onDataChange add user to adapter list and notify on each position inserted each time. But calling notifyItemInserted(position) many times isn’t just going to look bad, it’s going to crash your app if the initial list is something like 200-500 items. Why not bundle and just notify once?

That’s a value listener which I set for user/id nodes. By the way, you can reuse listeners, just create one object and use them for each id. It doesn’t need to access any fields, everything is in the arguments.

UpdateUser method is simple, just replace user in your list with the received and notifyChange on that position. NewUser method is a helpful one. It’s called ether when we fetch first initial list of users and when new users added after that. That’s where we use initialListSize, if we haven’t fetched the list yet, we increament counter each time and when it reaches the list size, we notify RecyclerView Adapter just one. After that, when new items are added we notify each time.

Reliable?

Is this counter reliable? If there’s a new item added during you fetching initial list, you will notify adapter before fetching all initial list. But then there’s still a callback for a new item added, so it is a good approach.

Unregister Listeners

Now there’s a really important part. Those listeners we add live during the app. They’re not being destroyed with your Activity/Fragment. If you don’t remove them, then with just few rotations, switching activities you’ll have multiple duplicated callbacks. Say there’s a new user added, you’ll get 5 callbacks for it. Most likely it’s not going to affect your app much, you might even not notice.

So you need to keep reference to listeners. I just make them as fields and since you can reuse same for same types, it’s not that many. Let’s say we set 5 listeners for those paths users/1, users/2, users/3…. We might be tempted to just call

None of them would work. You need to remove from a particular path, in this case id for each user : users/id. That’s why we also need to keep track of ids we add listeners to. That’s how we can iterate over those and remove them

 

Alright, that’s the main things for implementing Firebase with Geofire or just from any set of node if you want to optimize it and notify recyclerview adapter just once when fetching.

Thanks for reading, you can get source code here. Don’t forget to follow me on G+, Twitter, Facebook and share with friends if you think they will benefit from it!

 


  • Muhammad S’fan

    we need more details please ??
    and how to use Algolia
    and thanks for your effort.