I want to populate my recycler view so that, I can see who are the people/places nearby. I am using GeoFire to Query my database, which looks something like this.
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latLngCenter.latitude, latLngCenter.longitude), 0.1);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
System.out.println(String.format("Key %s entered the search area at [%f,%f]", key, location.latitude, location.longitude));
Log.e("TAG", key + location.latitude + location.longitude);
}
@Override
public void onKeyExited(String key) {
System.out.println(String.format("Key %s is no longer in the search area", key));
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
System.out.println(String.format("Key %s moved within the search area to [%f,%f]", key, location.latitude, location.longitude));
Log.e("TAG", key + location.latitude + location.longitude);
}
@Override
public void onGeoQueryReady() {
System.out.println("All initial data has been loaded and events have been fired!");
}
@Override
public void onGeoQueryError(DatabaseError error) {
System.err.println("There was an error with this query: " + error);
}
});
and I am using this Firebase RecyclerView
RecyclerView recycler = (RecyclerView) findViewById(R.id.RecyclerView);
recycler.setHasFixedSize(true);
recycler.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerAdapter<Chat, ChatHolder> mAdapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(Chat.class, R.layout.recyclerview, ChatHolder.class, mUsers) {
@Override
public void populateViewHolder(final ChatHolder chatMessageViewHolder, final Chat chatMessage, int position) {
chatMessageViewHolder.setName(chatMessage.getName());
chatMessageViewHolder.setText(chatMessage.getText());
chatMessageViewHolder.setTimestamp(chatMessage.getTimestamp());
}
};
recycler.setAdapter(mAdapter);
with these Chat Holder class and chat object class
public static class ChatHolder extends RecyclerView.ViewHolder {
View mView;
public ChatHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name) {
TextView field = (TextView) mView.findViewById(R.id.textViewName);
field.setText(name);
}
public void setText(String text) {
TextView field = (TextView) mView.findViewById(R.id.textViewMessage);
field.setText(text);
}
public void setTimestamp(String text) {
TextView field = (TextView) mView.findViewById(R.id.textViewTime);
field.setText(text);
}
}
public static class Chat {
String name;
String text;
String uid;
String timestamp;
public Chat() {
}
public Chat(String name, String uid, String message, String timestamp) {
this.name = name;
this.text = message;
this.uid = uid;
this.timestamp = timestamp;
}
public String getName() {
return name;
}
public String getUid() {
return uid;
}
public String getText() {
return text;
}
public String getTimestamp() {
return timestamp;
}
}
Currently this, adapter which is provided in FirebaseUI library, populates recyclerview so that, only one reference is used and all child events are shown in the view, Now, I want to populate my recyclerView so that when ever a key enters it populates my recyclerview based on my key = to my reference, this how my firebase database looksmy firebase database
It'll be simpler to push all data (which is also uid
) you have retrieved from geofire to a new node to store geofire results in firebase, something like
my-node //your new firebase node to store all uids retrieved from geofire
- {chatUid}: true //true is just a dummy data, you can use anything else except null and empty string.
- {chatUid}: true
- ...
and set FirebaseRecyclerAdapter
ref to that node.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("my-node");
FirebaseRecyclerAdapter fra = new FirebaseRecyclerAdapter<Boolean, MyVH>(Boolean.class, R.layout.my_layout, MyVH.class, ref) { ... }
and then, in populateViewHolder()
method in your implementation of FirebaseRecyclerAdapter
, you can use the String key to fetch data from main node that contains the data.
public void populateViewHolder(MyVH viewHolder, Boolean model, int position){
// Get references of child views
final TextView nameTextView = viewHolder.getItemView().findViewById(R.id.my_name_text_view_in_vh_layout);
final TextView addressTextView = viewHolder.getItemView().findViewById(R.id.my_address_text_view_in_vh_layout);
// Key in this position.
String key = getRef(position).key;
// Query the full data of the current key located in the `main-data-node`
FirebaseDatabase.getInstance().getReference("main-data-node").child(key).addValueEventListener(new ValueEventListener(){
... //Truncated onCancelled
@Override
public void onDataChange(snap: DataSnapshot){
MyDataModel model = snap.getValue(MyDataModel.class);
nameTextView = model.getName();
addressTextView = model.getAddress();
}
}
}
// The data model class
public class MyDataModel {
private String name;
private String address;
... // Truncated getter, setter, constructor
}
For any changes in geofire result, just push those results to my-node
, and it will automatically informs your FirebaseRecyclerAdapter
.
P.S. I'm too lazy to match my solution to your data model (sorry), so I made a simplified sample class, so if anyone stumbled upon this, they can understand it easier.
P.S.S. It's been a while since I code in java, I mainly use kotlin (and you soon should too lol), so, if there're some syntax mistakes out there, feel free to edit.
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