Firebase搜索用户时保留排除当前用户条件后搜索失效求助
问题描述
在Flutter项目中使用Firebase Firestore实现用户搜索功能时遇到异常:调用searchPeople函数时,只有移除.where('user_id', isNotEqualTo: user!.uid)这行代码,才能根据用户输入进行过滤;但业务上需要保留这行代码以排除当前用户信息,移除后搜索功能可正常运行。
问题代码
import 'package:flutter/material.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:snap_clone/widget/add_friend_widget.dart'; import 'package:firebase_auth/firebase_auth.dart'; class AddFriendScreen extends StatefulWidget { const AddFriendScreen({super.key}); @override State<AddFriendScreen> createState() => _AddFriendScreenState(); } User? user = FirebaseAuth.instance.currentUser; class _AddFriendScreenState extends State<AddFriendScreen> { int _currentIndex = 0; var controller = TextEditingController(); Stream<QuerySnapshot> stream = FirebaseFirestore.instance .collection('users') .where('user_id', isNotEqualTo: user!.uid) .snapshots(); @override void initState() { super.initState(); } @override Widget build(BuildContext context) { Widget currentPage = const AddFriendScreen(); if (_currentIndex == 1) { currentPage = const AddFriendScreen(); } return Scaffold( backgroundColor: Colors.black, body: Container( child: Column( children: [ Container( color: Colors.white, padding: const EdgeInsets.only(bottom: 10), child: Column( children: [ Row( children: [ Expanded( child: Container( height: 50, margin: const EdgeInsets.only(left: 30), decoration: BoxDecoration( borderRadius: BorderRadius.circular(80), color: Colors.grey[200], ), child: Container( padding: const EdgeInsets.only(left: 15, right: 15), child: Row( children: [ const Icon( Icons.search_outlined, size: 30, ), Expanded( child: Container( padding: const EdgeInsets.only(bottom: 15, right: 5), child: TextField( keyboardType: TextInputType.name, onChanged: (value) { searchPeople(value); }, cursorColor: Colors.black, decoration: const InputDecoration( enabledBorder: InputBorder.none, focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.black), ), ), controller: controller, ), ), ), ], ), ), ), ), ], ), ], ), ), ], ), ), ); } // Define the search function here void searchPeople(String query) { setState(() { stream = FirebaseFirestore.instance .collection('users') .orderBy('user_id') .startAt([query]).endAt([query + '\uf8ff']) .where('user_id', isNotEqualTo: user!.uid) .snapshots(); }); } }
解决方案
1. 修正搜索字段逻辑
代码中错误地以user_id作为搜索目标字段,但用户输入的应该是用户名(如displayName)而非Firebase自动生成的UID,这是导致搜索失效的核心原因之一。调整搜索字段为实际的用户名字段:
2. 调整查询顺序并创建复合索引
Firestore要求同时使用where(不等条件)和orderBy时,必须创建对应的复合索引。建议将where条件放在orderBy之前(逻辑更清晰,不影响功能)。
修正后的searchPeople函数:
void searchPeople(String query) { setState(() { stream = FirebaseFirestore.instance .collection('users') .where('user_id', isNotEqualTo: user!.uid) .orderBy('displayName') // 替换为你的用户名字段,比如displayName或username .startAt([query]) .endAt([query + '\uf8ff']) .snapshots(); }); }
3. 创建复合索引
运行修正后的代码后,控制台会抛出索引缺失的错误,其中包含一个直接跳转Firebase控制台的链接,点击该链接即可自动生成所需的复合索引(包含user_id和你指定的用户名字段)。
额外说明
如果你的users集合中存储用户名的字段不是displayName,请将代码中的displayName替换为实际字段名。
内容的提问来源于stack exchange,提问作者Mohamad Bdeir
相关产品推荐
相关产品推荐

