Firebase Search Can't Show Results - java

I want to make search data on my app based on Firebase. I've followed instructions on internet how to make search Firebase.
It shows no error, but when I clicked search button, my recycleview is empty, no data showed.
Here is my code:
btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String searchText = search_cust.getText().toString();
firebaseCustSearch(searchText);
}
});
This is my firebase search method
private void firebaseCustSearch(String searchText) {
Query firebaseSearchQuery = databaseCustomer.orderByChild("custName").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerOptions customerOptions = new FirebaseRecyclerOptions.Builder<Customer>()
.setQuery(firebaseSearchQuery, Customer.class).build();
adapter = new FirebaseRecyclerAdapter<Customer, CustomerList.ViewHolder>(customerOptions) {
#Override
protected void onBindViewHolder(#NonNull CustomerList.ViewHolder holder, int position, #NonNull Customer model) {
holder.setname(model.getCustName());
holder.setaddress(model.getCustAddress());
Toast.makeText(CRUDCustomer.this, model.custName,Toast.LENGTH_SHORT).show();
}
#NonNull
#Override
public CustomerList.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
};
listViewCustomer.setAdapter(adapter);
listViewCustomer.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
}
ViewHolder
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Customer customer = customerList.get(position);
holder.textName.setText(customer.getCustName());
holder.textAddress.setText(customer.getCustAddress());
holder.textPhone.setText(customer.getCustPhone());
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView textName ;
public TextView textAddress;
public TextView textPhone ;
public ViewHolder(#NonNull View view){
super(view);
this.textName = (TextView)view.findViewById(R.id.cust_name);
this.textAddress = (TextView)view.findViewById(R.id.cust_address);
this.textPhone = (TextView)view.findViewById(R.id.cust_phone);
}
public void setname(String name){
textName.setText(name);
}
public void setaddress(String address){
textAddress.setText(address);
}
}

private void search(String text) {
List filterdNames = new ArrayList<>();
for (Modelclass s : modelclass) {
if (s.getname.contains(text)) {
search.add(s);
}
}
//calling a method of the adapter class and passing the filtered list
sampleAdapter.filterList(filterdNames);
}

Related

Cannot resolve method 'getRef(int)'

here is the error I want to delete data from firebase using .removeValue(); but can't fetch the key inside child using .child(getRef(position).getKey()); it says "Cannot resolve method 'getRef(int)'"
I tried to get the key using getter & setter in model class, but that too didn't work!
Android Studio it does not resolve getRef(int) method. Here is the code:
public class RecyclerContactAdapter extends RecyclerView.Adapter<RecyclerContactAdapter.ViewHolder> {
Context context;
ArrayList<User> list;
DataSnapshot snapshot;
FirebaseFirestore firestore;
FirebaseAuth auth;
DatabaseReference reference;
//for search
public void setFilteredList(ArrayList<User> filteredList){
this.list = filteredList;
notifyDataSetChanged();
}
public RecyclerContactAdapter(Context context, ArrayList<User>list){
this.context = context;
this.list = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.contact_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
User user = list.get(position);
// String id1 = list.get(position).getKey();
holder.name.setText(user.getName());
holder.chn.setText(user.getChn());
holder.shn.setText(user.getShn());
holder.phone.setText(user.getPhone());
holder.hostel_optn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseDatabase.getInstance().getReference().child("HostelSwappingDatabase")
.child(getRef(position).getKey())
.removeValue();
}
});
holder.setIsRecyclable(false);
}
#Override
public int getItemCount() {
return list.size();
}
//
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
//
public static class ViewHolder extends RecyclerView.ViewHolder{
TextView name, chn, shn, phone;
ImageView hostel_optn;
public ViewHolder(View itemView){
super(itemView);
name = itemView.findViewById(R.id.name);
chn = itemView.findViewById(R.id.chn);
shn = itemView.findViewById(R.id.shn);
phone = itemView.findViewById(R.id.phone);
hostel_optn = itemView.findViewById(R.id.hostel_optn);
}
}
}
To delete any data instance from Firebase, one must implement FirebaseRecyclerAdapter as mentioned here
also get help from this video, if required click here.

Firestore recycler adapter - disappearing items after scrolling

I'm trying to create chatting service for my project, in order to do that I store my messages in a Firestore database that I fetch from the server and assign the text comparing the sender id to current user id.
When I start the activity, the messages show properly, but when I scroll down, either my messages stop showing up, or other user's messages disappear, depending whether on which account the chat is opened.
I can't seem to figure out why that happens.
My readMessages function:
private void readMessages(){
Query query = DataRef.collection("rooms").document(roomID).collection("messages").orderBy("timestamp", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<MessageModel> options = new FirestoreRecyclerOptions.Builder<MessageModel>().setQuery(query, MessageModel.class).build();
adapter = new FirestoreRecyclerAdapter<MessageModel, MessageAdapter.ViewHolder>(options) {
#Override
protected void onBindViewHolder(MessageAdapter.ViewHolder holder, int position, MessageModel model) {
if (myUid.equals(model.getUid())) {
Log.d(TAG, "status1");
holder.msg_right.setText(String.valueOf(model.getMsg()));
holder.msg_left.setVisibility(View.INVISIBLE);
holder.profile_image.setVisibility(View.INVISIBLE);
holder.msg_nick.setVisibility(View.INVISIBLE);
}
else
{
DataRef.collection("users").document(String.valueOf(model.getUid())).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot document = task.getResult();
msgNick = document.getString("usernm");
}
});
holder.msg_nick.setText(msgNick);
holder.msg_left.setText(String.valueOf(model.getMsg()));
holder.msg_right.setVisibility(View.INVISIBLE);
Log.d(TAG, "status0" );
}
}
#NonNull
#Override
public MessageAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message,parent,false);
return new MessageAdapter.ViewHolder(v);
}
};
adapter.startListening();
recyclerView.setAdapter(adapter);
}
My message adapter class:
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return 0;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView msg_right;
public ImageView profile_image;
public TextView msg_left;
public TextView msg_nick;
public ViewHolder(View itemView) {
super(itemView);
msg_right = itemView.findViewById(R.id.msg_right);
profile_image = itemView.findViewById(R.id.msg_leftavatar);
msg_left = itemView.findViewById(R.id.msg_left);
msg_nick = itemView.findViewById(R.id.msg_nick);
}
}
}
State of the chat before scrolling down and up:
"
And after doing so:
Please try to move the blow block of code of setting the holder members within the callback listener in else statement.
private void readMessages(){
Query query = DataRef.collection("rooms").document(roomID).collection("messages").orderBy("timestamp", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<MessageModel> options = new FirestoreRecyclerOptions.Builder<MessageModel>().setQuery(query, MessageModel.class).build();
adapter = new FirestoreRecyclerAdapter<MessageModel, MessageAdapter.ViewHolder>(options) {
#Override
protected void onBindViewHolder(MessageAdapter.ViewHolder holder, int position, MessageModel model) {
if (myUid.equals(model.getUid())) {
Log.d(TAG, "status1");
holder.msg_right.setText(String.valueOf(model.getMsg()));
holder.msg_left.setVisibility(View.INVISIBLE);
holder.profile_image.setVisibility(View.INVISIBLE);
holder.msg_nick.setVisibility(View.INVISIBLE);
}
else
{
DataRef.collection("users").document(String.valueOf(model.getUid())).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot document = task.getResult();
msgNick = document.getString("usernm");
holder.msg_nick.setText(msgNick);
holder.msg_left.setText(String.valueOf(model.getMsg()));
holder.msg_right.setVisibility(View.INVISIBLE);
Log.d(TAG, "status0" ); }
});
}
}

how can fillter the recyclerView

how can i filter Recycler View using SearchView
i try all the video tuturial but all of them get thier item Recycler View from a list
but i get my item from db and dont know how should i do this
this is my adapter Code
public class AthleteAdapter extends RecyclerView.Adapter<AthleteAdapter.AthleteHolder> {
private List<Athlete> athletes = new ArrayList<>();
private OnItemClickListener listener;
#NonNull
#Override
public AthleteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.athlete_item, parent, false);
return new AthleteHolder(itemview);
}
#Override
public void onBindViewHolder(#NonNull AthleteHolder holder, int position) {
Athlete currnetAthlete = athletes.get(position);
holder.textViewName.setText(currnetAthlete.getAthlete_name());
holder.textViewLastname.setText(currnetAthlete.getAthlete_lastname());
holder.textView_phonenumber.setText(currnetAthlete.getAthlete_phonenumber());
holder.textViewTime1.setText(String.valueOf(currnetAthlete.getSign_in_time()));
holder.textViewTime2.setText(String.valueOf(currnetAthlete.getCheck_tution_time()));
}
public void setAthletes(List<Athlete> athletes) {
this.athletes = athletes;
notifyDataSetChanged();
}
public Athlete getposition(int position) {
return athletes.get(position);
}
#Override
public int getItemCount() {
return athletes.size();
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public interface OnItemClickListener {
void onItemClick(Athlete athlete);
}
class AthleteHolder extends RecyclerView.ViewHolder {
private TextView textViewName, textViewLastname, textView_phonenumber, textViewTime1, textViewTime2;
public AthleteHolder(#NonNull View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.name_main);
textViewLastname = itemView.findViewById(R.id.lastname_main);
textView_phonenumber = itemView.findViewById(R.id.textView_number);
textViewTime1 = itemView.findViewById(R.id.time1);
textViewTime2 = itemView.findViewById(R.id.time2);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(athletes.get(position));
}
}
});
}
}
}
Step 1 : Get all data from db and give that list to Adapter
usersList = db.getAll();
adapter = new dataAdapter(getApplicationContext(), usersList);
adapter.setdatainterfacemethod(this);
Step 2 : get Text from Searchview
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
filter(s.toString());
}
return false;
}
});
Step 3 : compare searchview text and list text if exits then give list to adapter
public void filter(String text) {
List<Users> name = new ArrayList<>();
for (Users u : usersList) {
if (u.getNAME().toLowerCase().contains(text.toLowerCase())) {
name.add(u);
}
}
adapter.filterlist(name);
}
Step 4 :- change list and notify adapter (in adapter class)
public void filterlist(List<Users> name) {
this.usersList = name;
notifyDataSetChanged();
}
--------------------- Adapter class -----------------
public class dataAdapter extends RecyclerView.Adapter<dataAdapter.viewholder> {
public List<Users> usersList;
Context context;
dataInterface dataInterface;
public dataAdapter(Context context, List<Users> usersList) {
this.usersList = usersList;
this.context = context;
}
public void setdatainterfacemethod(dataInterface dataInterface) {
this.dataInterface = dataInterface;
}
#NonNull
#Override
public viewholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.include_recycle_demo, viewGroup, false);
return new viewholder(view);
}
#Override
public void onBindViewHolder(#NonNull final viewholder viewholder, final int i) {
}
#Override
public int getItemCount() {
return usersList.size();
}
public void filterlist(List<Users> name) {
this.usersList = name;
notifyDataSetChanged();
}
public class viewholder extends RecyclerView.ViewHolder {
public viewholder(#NonNull View itemView) {
super(itemView);
}
}
}

getAdapterPosition not doing what it is supposed to do

I have a RecyclerView Fragment to which I added a Filter Search in an edit text. It works, but when I click in a Card of the Recycler, it goes to the wrong detail. My best guess is that it's getting the wrong position from the getAdapterPosition since let's say I have this list {a,b,c,d,e,f,g,h}. when I filter and get two itmes left like {d,g}. If I click d it redirects to a, if I click g it redirects to b.
This is my RecyclerView
public class RecyclerProfile extends Fragment implements
Adapter.AdapterListener, com.example.cake.profiling.Adapter.SearchListener
{
private RecyclerListener recyclerListener;
private List<Profile> profiles = (new DAOProfile()).getProfile();
private Adapter recyclerAdapter= new Adapter(profiles, this);
public RecyclerProfile() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_recycler_profile,
container, false);
RecyclerView recyclerView = view.findViewById(R.id.recyclerProfile);
EditText editText = view.findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int
count) {
}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new
LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerAdapter);
setHasOptionsMenu(true);
return view;
}
private void filter(String text){
ArrayList<Profile> filteredList = new ArrayList<>();
for (Profile profile: profiles){
if (profile.getName().toLowerCase().contains(text.toLowerCase())){
filteredList.add(profile);
}
}
recyclerAdapter.filterList(filteredList);
profiles = new ArrayList<>(filteredList);
}
#Override
public void listen(Profile profile, Integer position) {
recyclerListener.send(profile, position);
}
#Override
public void profileSelected(Profile profile) {
}
//INTERFACE
public interface RecyclerListener {
void send(Profile profile, Integer position);
}
//ON ATTACH
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.recyclerListener = (RecyclerListener) context;
}
}
This is my Adapter
public class Adapter extends RecyclerView.Adapter<Adapter.ProfileViewHolder> {
private List<Profile> profiles;
private AdapterListener adapterListener;
//CONSTRUCTOR
public Adapter(List<Profile> profiles,AdapterListener adapterListener) {
this.profiles = profiles;
this.adapterListener = adapterListener;
}
#NonNull
#Override
public Adapter.ProfileViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.card_profile, parent, false);
ProfileViewHolder profileViewHolder = new ProfileViewHolder(view);
return profileViewHolder;
}
#Override
public void onBindViewHolder(#NonNull Adapter.ProfileViewHolder holder, int position) {
Profile profile = profiles.get(position);
holder.setter(profile);
}
#Override
public int getItemCount() {
return profiles.size();
}
public void filterList (ArrayList<Profile> filteredList){
profiles = filteredList;
notifyDataSetChanged();
}
//VIEWHOLDER
class ProfileViewHolder extends RecyclerView.ViewHolder{
private ImageView image;
private TextView name;
public ProfileViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.nameProfile);
image = itemView.findViewById(R.id.imageProfile);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Profile profile = profile.get(getAdapterPosition());
adapterListener.receive(profile, getAdapterPosition());
}
});
}
public void setter (Profile profile){
name.setText(profile.getName());
image.setImageResource(profile.getImage());
}
}
public interface AdapterListener {
void receive(Profile profile, Integer position);
}
}
getAdapterPosition()
this will return the position of the item of current data set. This is what I'd do
class ProfileViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView image;
private TextView name;
Profile mProfile;
public ProfileViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.nameProfile);
image = itemView.findViewById(R.id.imageProfile);
name.setOnClickListener(this);
image.setOnClickListener(this);
}
public void setter (Profile profile){
if(profile != null) {
mProfile = profile;
name.setText(mProfile.getName());
image.setImageResource(mProfile.getImage());
}
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.item_nameProfile:
case R.id.item_imageProfile:
for(int i = 0 ; i < profiles.size() ; i++) {
if(profiles.get(i).getName().equalsIgnoreCase(mProfile.getName()) {
adapterListener.receive(profiles.get(i), i);
break;
}
}
break;
}
}
public interface AdapterListener {
void receive(Profile profile, Integer position);
}
}

How to update Datamodel in RecyclerviewAdapter

i created a recyclerview where i can see all my chats. Every item contains the name, the lastmessage and a thumb. if the user send or receive a new message, it should be displayed there and the item should go to position 0. Now i have the problem that the message is displayed, but the chat item goes only to the first position if the position was not 0 before. So if i receive two new messages its not working anymore because the data model is the same like before. So how can i fit my data model to the current position of every item. Currently my adapter looks like this:
private static final String TAG = "CustomAdapter";
private Context context;
private Activity mActivity;
private List<MatchesObject> matchesList;
private String currentUid;
public matchadapterino(Activity mActivity, ArrayList<MatchesObject> mDataSet) {
this.mActivity = mActivity;
this.matchesList = mDataSet;
}
// Create new views (invoked by the layout manager)
#Override
public matchadapterino.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.matchesitem, viewGroup, false);
return new matchadapterino.ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final matchadapterino.ViewHolder viewHolder, final int position) {
viewHolder.getMatchname().setText(matchesList.get(position).getUsername());
if (!matchesList.get(position).getProfileImageUrl().equals("default")) {
Picasso.with(mActivity).load(matchesList.get(position).getProfileImageUrl()).into(viewHolder.getMatchImage());
getLastMSG(matchesList.get(position).getUserId(), viewHolder.getLastMSG(), position);
viewHolder.getMatchImage().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mActivity, UserDetailView.class);
//
i.putExtra("userId", matchesList.get(position).getUserId());
mActivity.startActivity(i);
}
});
} else {
viewHolder.getMatchImage().setImageResource(R.mipmap.ic_launcher_round);
}
viewHolder.getForeground().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mActivity, Chat.class);
Bundle b = new Bundle();
b.putString("matchId", matchesList.get(position).getUserId());
i.putExtras(b);
mActivity.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return matchesList.size();
}
// Get element from your dataset at this position and replace the contents of the view
// with that element
public void removeItem(int position) {
matchesList.remove(matchesList.get(position));
notifyItemRemoved(position);
}
// Return the size of your dataset (invoked by the layout manager)
/**
* Provide a reference to the type of views that you are using (custom ViewHolder)
*/
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView matchname, lastMSG;
public ImageView matchImage;
private RelativeLayout foreground;
private RelativeLayout background;
public ViewHolder(View v) {
super(v);
currentUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
matchname = itemView.findViewById(R.id.matchname);
matchImage = itemView.findViewById(R.id.matchImages);
lastMSG = itemView.findViewById(R.id.lastmsg);
foreground = itemView.findViewById(R.id.foregroundmatch);
background = itemView.findViewById(R.id.backgroundmatch);
}
public RelativeLayout getForeground() {
return foreground;
}
public RelativeLayout getBackground() {
return background;
}
public TextView getLastMSG() {
return lastMSG;
}
public TextView getMatchname() {
return matchname;
}
public ImageView getMatchImage() {
return matchImage;
}
}
private void getLastMSG(final String userId, final TextView lastMSG, final int position) {
final String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users").child(userid).child("connections").child("matches").child(userId);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
notifyItemMoved(0, position);
Toast.makeText(mActivity, "position changed" + position, Toast.LENGTH_LONG).show();
if (dataSnapshot.child("lastMsgBy").getValue().toString().equals(userid)) {
lastMSG.setTextColor(Color.parseColor("#d2403a3a"));
String lastMsg = dataSnapshot.child("lastMsg").getValue().toString();
lastMSG.setText(lastMsg);
} else {
lastMSG.setTextColor(Color.parseColor("#000000"));
String lastMsg = dataSnapshot.child("lastMsg").getValue().toString();
lastMSG.setText(lastMsg);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}

Categories