所描述的问题涉及 Flutter 应用程序中的
onSearch
函数,该函数使用 Firestore 根据用户在搜索字段中输入的搜索词来检索和过滤用户列表。以下是问题的详细描述:
目标:
onSearch
功能的目标是根据用户在搜索字段中输入的搜索词来过滤用户列表。过滤后的用户应显示在屏幕上。
问题:执行搜索时,过滤后的用户列表不包含任何项目,即使应该存在与搜索词匹配的用户。这表明过滤未按预期工作,并且未根据搜索正确过滤用户。
分析:要找出问题的原因,需要检查几个点:
QuerySnapshot
的正确接收和转换。filteredUsers
列表与已过滤的用户。综上所述,所描述的问题涉及无法根据搜索词正确过滤用户列表,需要对过滤过程进行彻底的分析和修改才能解决。
以下是您尝试过的操作以及预期发生的情况的描述:
你尝试了什么:
onSearch
函数,以根据用户输入的搜索词过滤用户列表。onSearch
函数中构建了一个 Firestore 查询,以使用 isGreaterThanOrEqualTo
和 isLessThanOrEqualTo
条件按用户姓名过滤用户。filteredUsers
列表。filteredUsers
列表是否有任何更改。您期望发生什么:
onSearch
函数根据该词过滤用户列表。filteredUsers
列表。filteredUsers
列表,相应地显示过滤后的用户。void onSearch(String search) {
// Convert the search term to lowercase and uppercase for case-insensitive matching
String searchLower = search.toLowerCase();
String searchUpper = search.toUpperCase();
// Check if the search term is empty
if (search.isEmpty) {
setState(() {
// If search term is empty, set filteredUsers to the entire list of users
filteredUsers = List.from(users);
});
return;
}
// Perform Firestore query to filter users based on the search term
FirebaseFirestore.instance
.collection("Users")
.where("name", isGreaterThanOrEqualTo: searchLower)
.where("name", isLessThanOrEqualTo: '${searchUpper}z')
.snapshots()
.listen((QuerySnapshot<Map<String, dynamic>> snapshot) {
setState(() {
// Convert the snapshot into a list of QueryDocumentSnapshot
filteredUsers = snapshot.docs.cast<QueryDocumentSnapshot<Map<String, dynamic>>>().toList();
});
// Debugging: Print the filtered users
print("Filtered Users: $filteredUsers");
});
}
您似乎正在此处进行字符串搜索:
String searchLower = search.toLowerCase();
String searchUpper = search.toUpperCase();
...
FirebaseFirestore.instance
.collection("Users")
.where("name", isGreaterThanOrEqualTo: searchLower)
.where("name", isLessThanOrEqualTo: '${searchUpper}z')
由于这些是字符串,因此顺序是字典顺序,并且按照该顺序,小写字符位于大写字符之后。作为参考,我们使用这个 ASCII 表:
如果
search
是 a
或 A
,则您的代码会搜索 name >= "a" AND name <= "A"
或以 ASCII 值 name >= 141 AND name <= 101
搜索,这始终是空结果集。
如果交换参数,就会得到结果。但您可能会得到更多结果,因为
"A"
和 "az"
之间有很多您可能不想要的值,例如 "B"
、"C"
等
总的来说,这不是实现不区分大小写搜索的好方法。上面执行了开始at/结束at操作。
如果您想搜索以 with
a
OR A
开头的结果,那将是一个 OR 查询,如下所示:
.where(
Filter.or(
Filter.and(
Filter("name", isGreaterThanOrEqualTo: "A"),
Filter("name", isLessThanOrEqualTo: "A~"),
),
Filter.and(
Filter("name", isGreaterThanOrEqualTo: "a"),
Filter("name", isLessThanOrEqualTo: "a~"),
),
));
)