Flutter中实现手机通讯录与Firebase用户列表的号码匹配筛选
Flutter中实现手机通讯录与Firebase用户列表的号码匹配筛选
嘿,我看你正在尝试把本地通讯录和Firebase用户列表按号码匹配,只显示两边都存在的用户对吧?你的现有代码里有个关键问题——直接用索引index同时取usersFirebase[index]和contactListProvider.usercontactlist[index]是完全不靠谱的,因为两个列表的顺序和长度都不一定对应,根本没法保证索引位置的号码是匹配的。我来帮你调整代码,实现正确的匹配逻辑:
核心思路
- 先把本地通讯录里的所有号码提取出来,放到一个
Set集合里(用Set是因为它的查找效率比List高很多) - 遍历Firebase返回的用户列表,筛选出号码存在于通讯录号码集合里的用户
- 最后把筛选后的用户列表展示出来
修改后的完整代码
Widget build(BuildContext context) { final contactListProvider = Provider.of<ContactProvider>(context); return Scaffold( appBar: Custom_appbar( title: 'Trusted Contacts', ), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.only(top: 8.0), child: contactListProvider.loadingcontact ? Center( child: CircularProgressIndicator(), ) : StreamBuilder<List<UserModel>?>( stream: MyFirebaseDB().userdata(), initialData: [], builder: (context, snapshot) { // 处理Firebase数据加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (!snapshot.hasData || snapshot.data!.isEmpty) { return Center(child: Text('暂无Firebase用户数据')); } // 1. 提取通讯录中的所有号码,转成Set(统一格式,比如去掉空格、+号前缀等,避免匹配失败) final contactNumbers = contactListProvider.usercontactlist .map((contact) { // 这里根据你的Contact模型的号码字段调整,比如contact.number // 统一格式:比如去掉所有非数字字符,确保匹配的一致性 return contact.number.replaceAll(RegExp(r'\D'), ''); }) .toSet(); // 2. 筛选Firebase中号码存在于通讯录的用户 final matchedUsers = snapshot.data!.where((fireUser) { // 同样统一Firebase用户号码的格式 final cleanFireNumber = fireUser.userNumber.toString().replaceAll(RegExp(r'\D'), ''); return contactNumbers.contains(cleanFireNumber); }).toList(); // 3. 展示筛选后的用户 if (matchedUsers.isEmpty) { return Center(child: Text('通讯录中暂无匹配的Firebase用户')); } return ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: matchedUsers.length, itemBuilder: (BuildContext context, int index) { final fireuser = matchedUsers[index]; // 这里可以根据需要展示用户的更多信息,比如姓名、头像等 return ListTile( title: Text(fireuser.userNumber.toString()), // subtitle: Text(fireuser.userName), // 如果有姓名字段的话 ); }, ); }, ), ), ), ); }
关键细节说明
- 号码格式统一:我加了去掉非数字字符的处理,因为通讯录里的号码可能带空格、+号或者括号,Firebase里的号码格式可能不一样,统一格式能避免明明号码相同却匹配不上的问题
- 使用Set存储通讯录号码:Set的
contains方法查找效率是O(1),比List的O(n)快很多,当通讯录数量大的时候差异会很明显 - 状态处理优化:补充了
ConnectionState.waiting的判断,同时处理了Firebase数据为空、匹配结果为空的情况,给用户更友好的提示 - 避免索引错误:不再用同一个索引去取两个不同列表的项,而是先筛选出匹配的用户列表,再基于这个列表构建UI
这样修改后,就能准确显示出同时存在于本地通讯录和Firebase用户列表中的用户啦!
备注:内容来源于stack exchange,提问作者Sikki Coding
相关产品推荐
相关产品推荐

