我正在尝试为从Firebase填充与会者的应用程序实现搜索功能。 “会议”对象具有一个包含用户ID的整数列表,应用程序转到firebase并为参加该特定会议的每个用户创建“用户”对象。
我正在尝试提供一个搜索功能,该功能将有助于根据用户名过滤和查找用户。
在这里检索用户对象,并将其作为芯片添加到recyclerview中:
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Integer selectedUser = mMeeting.getUsers().get(position);
String selectedUserString = String.valueOf(selectedUser);
FirebaseFirestore db = FirebaseFirestore.getInstance();
String user = FirebaseAuth.getInstance().getCurrentUser().getUid();
DocumentReference userDocRec = db.collection("users/"+user+"/clients").document(selectedUserString);
userDocRec.get()
.addOnSuccessListener((documentSnapshot) -> {
if (documentSnapshot.exists()) {
User thisUser = documentSnapshot.toObject(User.class);
String name = String.valueOf(thisUser.getFirstName()
+ " " + String.valueOf(thisUser.getSurName()));
String dateOfBirth = thisUser.getDateOfBirth();
Chip chip = ((Chip) holder.itemView);
chip.setChipText(name);
chip.setVisibility(View.VISIBLE);
chip.setChecked(mMeeting.getAttended().contains(selectedUser));
chip.setOnCloseIconClickListener(view -> {
Toast.makeText(mContext, name + " - DOB: " + dateOfBirth, Toast.LENGTH_SHORT).show();
});
userMap.put(position, thisUser);
}
}
).addOnFailureListener((e) -> {
Toast.makeText(mContext, "Cannot load user", Toast.LENGTH_SHORT).show();
}
);
我尝试了一个非常hacky的解决方案,每次与搜索功能交互时,适配器和recyclerviews都会重新加载,并且for循环仅填充用户名匹配或包含搜索词的芯片:
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
searchFilter = s;
AttendanceAdapter2 adapter = new AttendanceAdapter2(mMeeting, mContext,
(m) -> ((Callback<Meeting>) getActivity()).update(m));
recyclerView.setAdapter(adapter);
return false;
}
@Override
public boolean onQueryTextChange(String s) {
searchFilter = s;
AttendanceAdapter2 adapter = new AttendanceAdapter2(mMeeting, mContext,
(m) -> ((Callback<Meeting>) getActivity()).update(m));
recyclerView.setAdapter(adapter);
return false;
}
});
if (InterventionAttendanceFragment.searchFilter == "" ||
name.toLowerCase().contains(InterventionAttendanceFragment.searchFilter.toLowerCase())){
Chip chip = ((Chip) holder.itemView);
chip.setChipText(name);
chip.setVisibility(View.VISIBLE);
chip.setChecked(mMeeting.getAttended().contains(selectedUser));
chip.setOnCloseIconClickListener(view -> {
Toast.makeText(mContext, name + " - DOB: " + dateOfBirth, Toast.LENGTH_SHORT).show();
});
}
这不是一个很好的解决方案,而且非常耗资源,每次都要经过Firebase,并且在recyclerview中也会留下空白,因为这些筹码与搜索字词不匹配。
我找到了一些不错的解决方案,但是它们依赖于通过列表填充的“用户”,并且由于现有的基础架构和应用程序的性质,我无法对其进行太多更改以使其开始运行不在名单上,而不是火力地堡:
How to filter a RecyclerView with a SearchView
https://www.androidhive.info/2017/11/android-recyclerview-with-search-filter-functionality/
任何帮助或指针,以及可能的替代解决方案或库,将不胜感激!
当前正在运行Android Studio 3.1.4
答案 0 :(得分:0)
Firebase Firestore数据库的查询功能非常有限,但是您可以使用云功能并在服务器端执行过滤过程。我已经多次遇到此问题,但是不幸的是,firestore当前不支持这种复杂的查询,但效果更好比它的姐妹实时数据库更重要。