Flutter中如何在Firestore中筛选当前登录用户邮箱对应的任务
实现方案
最优方案:服务端查询过滤(推荐)
这种方式直接在Firestore查询阶段完成过滤,不需要拉取全集合数据,性能更好,也不会泄露其他用户的任务数据,是官方推荐的实现方式。
具体修改步骤
- 第一步:修正Stream查询条件,添加where过滤
将原来的stream参数替换为如下代码,直接在查询阶段就过滤出邮箱匹配的任务:
// 用户未加载完成时返回空流,避免空指针异常 stream: loggedInUser != null ? _firestore.collection('tasks').where('email', isEqualTo: loggedInUser!.email).snapshots() : const Stream.empty(),
- 第二步:补充空数据判断逻辑
在原有snapshot.hasData判断之后,新增查询结果为空的判断,匹配到空数据时展示空状态UI:
if (!snapshot.hasData) { // 原有加载状态逻辑保持不变 } // 新增:当前用户无匹配任务时展示空状态 if (snapshot.data!.docs.isEmpty) { return Padding( padding: EdgeInsets.only(top: 50, bottom: 50), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "There is nothing to show for now!", style: GoogleFonts.poppins(fontSize: 20), ), InkWell( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => AddTask()), ); }, child: Container( height: 80, width: 80, decoration: BoxDecoration( color: Colors.blueAccent, gradient: LinearGradient( begin: Alignment.topRight, end: Alignment.bottomRight, colors: [Colors.blue, Colors.blueAccent], ), shape: BoxShape.circle, ), child: Center( child: Icon( Icons.add, size: 35, color: Colors.white, ), ), ), ), ], ), ); }
- 第三步(可选优化):优化用户状态监听逻辑
你当前的getCurrentUser是异步调用,可能出现页面构建完成但用户还未加载完成的时序问题,可以改用FirebaseAuth自带的登录状态流监听,逻辑更稳定:
@override void initState() { super.initState(); // 监听登录状态变化,自动更新登录用户信息 _auth.authStateChanges().listen((user) { setState(() { loggedInUser = user; }); }); }
- 第四步(安全建议):配置Firestore安全规则
为了避免其他用户非法获取任务数据,在Firebase控制台的安全规则页添加如下规则,限制用户只能访问自己的任务:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /tasks/{taskId} { allow read, write: if request.auth != null && request.auth.email == resource.data.email; } } }
备选方案:客户端过滤(不推荐)
如果你暂时不想修改查询逻辑,也可以在拿到全集合数据后在客户端做过滤,仅需修改文档映射逻辑即可:
snapshot.data!.docs.where((document) { Map<String, dynamic> data = document.data()! as Map<String, dynamic>; return data['email'] == loggedInUser?.email; }).map((DocumentSnapshot document) { // 原有构建Card的逻辑保持不变 }).toList()
注意:这种方式会拉取所有用户的任务数据,浪费流量且存在数据泄露风险,仅适合临时测试使用,不建议线上环境使用。
内容的提问来源于stack exchange,提问作者themmfa
相关产品推荐
相关产品推荐

