如何实现登录用户仅查看自身信息?附Flutter+Firebase示例代码
实现登录用户仅查看自身笔记/待办的解决方案
你的问题核心在于没有为笔记/待办数据关联当前登录用户的唯一标识,且查询逻辑未做用户隔离,导致数据查询范围覆盖全部用户内容,出现跨用户查看的异常。以下是具体解决步骤及示例代码:
1. 为数据添加用户关联标识
每个笔记/待办文档必须存储当前登录用户的uid(Firebase Auth生成的唯一用户ID,比邮箱更安全),以此区分数据归属。
修改注册逻辑(优化用户信息存储)
在现有_register方法中,建议存储用户uid而非明文密码(Firebase Auth已管理密码,明文存储有安全风险):
Future<void> _register() async { try { UserCredential userCredential = await firebaseAuth.createUserWithEmailAndPassword( email: email.text, password: password.text ); // 获取用户唯一uid String userId = userCredential.user!.uid; // 存储用户基础信息 await fireStore.collection("todo_user").doc(userId).set({ "email": email.text, "uid": userId }); } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { print('密码强度不足'); } else if (e.code == 'email-already-in-use') { print('该邮箱已注册'); } } catch (e) { print(e); } }
2. 添加笔记时关联当前用户uid
创建笔记文档时,必须插入当前登录用户的uid,确保数据归属正确:
Future<void> addNote(String noteContent) async { // 获取当前登录用户 User? currentUser = firebaseAuth.currentUser; if (currentUser == null) { // 用户未登录,可跳转登录页或提示 return; } await fireStore.collection("notes").add({ "content": noteContent, "userId": currentUser.uid, // 关联当前用户标识 "createdAt": FieldValue.serverTimestamp() }); }
3. 查询仅当前用户的笔记
获取笔记列表时,通过where条件过滤出属于当前登录用户的文档:
Stream<QuerySnapshot> getUserNotes() { User? currentUser = firebaseAuth.currentUser; if (currentUser == null) { // 返回空流或处理未登录状态 return const Stream.empty(); } // 仅查询当前用户的笔记 return fireStore.collection("notes") .where("userId", isEqualTo: currentUser.uid) .orderBy("createdAt", descending: true) .snapshots(); }
在UI中使用该Stream展示数据:
@override Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: getUserNotes(), builder: (context, snapshot) { if (snapshot.hasError) { return const Text('加载出错'); } if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 构建笔记列表 return ListView( children: snapshot.data!.docs.map((doc) { Map<String, dynamic> data = doc.data() as Map<String, dynamic>; return ListTile( title: Text(data["content"]), subtitle: Text(data["createdAt"]?.toDate().toString() ?? ""), ); }).toList(), ); }, ); }
4. 设置Firestore安全规则(关键,防止非法访问)
即使客户端做了逻辑过滤,仍需通过Firestore安全规则限制用户仅能访问自身数据,避免恶意客户端绕过逻辑:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 限制用户仅能读写自己的笔记 match /notes/{note} { allow read, write: if request.auth != null && request.auth.uid == resource.data.userId; } // 限制用户仅能读写自己的账户信息 match /todo_user/{user} { allow read, write: if request.auth != null && request.auth.uid == user; } } }
5. 完善登录逻辑
补充现有代码中未实现的_sigIn方法:
Future<void> _sigIn() async { try { await firebaseAuth.signInWithEmailAndPassword( email: email.text, password: password.text ); // 登录成功跳转至笔记页面 Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => NotesPage())); } on FirebaseAuthException catch (e) { if (e.code == 'user-not-found') { print('未找到该用户'); } else if (e.code == 'wrong-password') { print('密码错误'); } } catch (e) { print(e); } }
并在登录页面的build方法中添加登录按钮:
// 在registerElevatedButton()后添加 customSizedBox(), loginElevatedButton(),
内容的提问来源于stack exchange,提问作者batucode
相关产品推荐
相关产品推荐

