Flutter中查询Firebase List数据:检测特定UID是否存在
问题分析与解决方案
你的核心问题是错误地将对象数组当作字符串数组进行判断:follower字段是包含uid和crDate的对象列表,不是单纯的UID字符串列表,所以直接用contains('目标UID')永远返回false。
1. 修正现有UI判断逻辑
将UI中的判断条件改为遍历follower数组,检查是否存在uid匹配的对象:
Obx( () { if (_followerCtrl.followerInfoLstByUid.isNotEmpty) { // 遍历follower对象数组,检查是否有匹配的uid final hasTargetFollower = _followerCtrl.followerInfoLstByUid[0].follower .any((followerItem) => followerItem.uid == 'P4HXDFEeDFTU8bzJCRhNPDZLO6m1'); if (hasTargetFollower) { return Container( margin: EdgeInsets.fromLTRB(0, 0, 16, 0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: black, ), height: 24, width: 82, child: TextButton( onPressed: () {}, child: Text('팔로우', style: TextStyle(color: white)), )); } } return Container(); }, )
2. 优化方案:直接在Firebase查询中过滤(更高效)
如果你的需求只是判断是否存在该关注者,不需要拉取整个follower列表,可以在API层新增一个查询方法,直接从Firebase获取结果,减少客户端数据处理:
API层新增方法
Stream<bool> checkIfUserIsFollower(String userUid, String targetUid) { return FirebaseFirestore.instance .collection('Follower') .where('uid', isEqualTo: userUid) // 注意:Firestore的arrayContains需要匹配整个对象,若crDate不固定,此方法不适用 .where('follower', arrayContains: {'uid': targetUid, 'crDate': '对应日期'}) .snapshots() .map((snapshot) => snapshot.docs.isNotEmpty); }
数据结构优化建议
如果crDate是动态生成的,上述arrayContains无法匹配(因为需要完全一致的对象),建议将follower字段重构为UID字符串数组:
{ "uid": "userUid", "followerUids": ["P4HXDFEeDFTU8bzJCRhNPDZLO6m1", "其他UID"], "followerDetails": [{"uid": "...", "crDate": "..."}] // 保留详情(可选) }
这样查询会更简单高效:
Stream<bool> checkIfUserIsFollower(String userUid, String targetUid) { return FirebaseFirestore.instance .collection('Follower') .where('uid', isEqualTo: userUid) .where('followerUids', arrayContains: targetUid) .snapshots() .map((snapshot) => snapshot.docs.isNotEmpty); }
Controller层使用优化后的查询
class FollowerController extends GetxController { final RxBool isTargetFollower = false.obs; void checkFollowerStatus(String userUid, String targetUid) { _followerApi.checkIfUserIsFollower(userUid, targetUid).listen((exists) { isTargetFollower.value = exists; }); } }
UI层简化代码
Obx(() => _followerCtrl.isTargetFollower.value ? Container( margin: EdgeInsets.fromLTRB(0, 0, 16, 0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: black, ), height: 24, width: 82, child: TextButton( onPressed: () {}, child: Text('팔로우', style: TextStyle(color: white)), )) : Container())
3. 额外优化:修正Controller的数据结构
从你的数据库结构看,每个userUid应该对应唯一的Follower文档,所以followerInfoLstByUid用RxList不合理,建议改为Rx<FollowerInfo?>:
class FollowerController extends GetxController { final Rx<FollowerInfo?> followerInfoByUid = Rx<FollowerInfo?>(null); void fetchFollowerByUid(String uid) { _followerApi.fetchColDataByUid(uid).listen((event) { loading(true); followerInfoByUid.value = event.docs.isNotEmpty ? FollowerInfo.fromMap(event.docs.first.id, event.docs.first.data() as Map<String, dynamic>) : null; loading(false); }); } }
这样UI中就不需要取[0],避免数组为空时的索引错误。
内容的提问来源于stack exchange,提问作者Lookup
相关产品推荐
相关产品推荐

