如何基于Firebase认证用户UID添加并获取用户详情
解决方案
1. 添加Firebase Firestore依赖
首先在你的pubspec.yaml中添加Cloud Firestore依赖,确保版本与现有FlutterFire依赖匹配:
dependencies: flutter: sdk: flutter firebase_auth: ^4.16.0 flutterfire_ui: ^0.4.3+2 cloud_firestore: ^4.15.0
执行flutter pub get完成依赖安装。
2. 创建用户详情收集页面
用户注册成功首次登录时,需要填写姓名、地址等信息,创建UserDetailsForm页面处理数据收集与存储:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; class UserDetailsForm extends StatefulWidget { const UserDetailsForm({super.key}); @override State<UserDetailsForm> createState() => _UserDetailsFormState(); } class _UserDetailsFormState extends State<UserDetailsForm> { final _formKey = GlobalKey<FormState>(); final _nameController = TextEditingController(); final _addressController = TextEditingController(); final _phoneController = TextEditingController(); final _auth = FirebaseAuth.instance; final _firestore = FirebaseFirestore.instance; Future<void> _saveUserDetails() async { if (_formKey.currentState!.validate()) { final currentUser = _auth.currentUser; if (currentUser != null) { await _firestore.collection('users').doc(currentUser.uid).set({ 'uid': currentUser.uid, 'email': currentUser.email, 'name': _nameController.text.trim(), 'address': _addressController.text.trim(), 'phone': _phoneController.text.trim(), 'createdAt': FieldValue.serverTimestamp(), }); if (mounted) { Navigator.pushReplacementNamed(context, '/home'); } } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('完善个人信息')), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( children: [ TextFormField( controller: _nameController, decoration: const InputDecoration(labelText: '姓名'), validator: (value) => value?.isEmpty ?? true ? '请输入姓名' : null, ), TextFormField( controller: _addressController, decoration: const InputDecoration(labelText: '地址'), validator: (value) => value?.isEmpty ?? true ? '请输入地址' : null, ), TextFormField( controller: _phoneController, decoration: const InputDecoration(labelText: '电话号码'), validator: (value) => value?.isEmpty ?? true ? '请输入电话号码' : null, keyboardType: TextInputType.phone, ), const SizedBox(height: 20), ElevatedButton( onPressed: _saveUserDetails, child: const Text('保存信息'), ), ], ), ), ), ); } }
3. 修改登录跳转逻辑
在MyHomePage的StreamBuilder中,判断用户是否已完善信息,决定跳转目标:
// 导入cloud_firestore import 'package:cloud_firestore/cloud_firestore.dart'; // 修改StreamBuilder的builder部分 builder: (context, snapshot) { if (snapshot.hasData) { final user = snapshot.data!; return FutureBuilder<DocumentSnapshot>( future: FirebaseFirestore.instance.collection('users').doc(user.uid).get(), builder: (context, docSnapshot) { if (docSnapshot.connectionState == ConnectionState.waiting) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } // 文档不存在则跳转到信息收集页 if (!docSnapshot.data!.exists) { return const UserDetailsForm(); } // 已有信息则跳转到主页 return HomePage(userDoc: docSnapshot.data!); }, ); } else { // 保留原有RegisterScreen代码 return RegisterScreen( headerBuilder: (context, constraints, _) { return Padding( padding: const EdgeInsets.all(20), child: AspectRatio( aspectRatio: 1, child: Image.network('https://firebase.flutter.dev/img/flutterfire_300x.png'), ), ); }, subtitleBuilder: (context, action) => Padding( padding: const EdgeInsets.only(bottom: 12), child: Text(action == AuthAction.signIn ? 'Welcome to ABC Delivery App! Please Login to the App' : 'Welcome to ABC Delivery App! Please SignUp to Enter App' ), ), footerBuilder: (context, _) => const Padding( padding: EdgeInsets.only(top: 16), child: Text( 'By Singing In you agree to our terms and conditions', style: TextStyle(color: Colors.grey), ), ), providerConfigs: const [ EmailProviderConfiguration(), ], ); } }
4. 主页显示用户详情
修改HomePage接收用户数据并展示:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; class HomePage extends StatelessWidget { final DocumentSnapshot userDoc; const HomePage({super.key, required this.userDoc}); @override Widget build(BuildContext context) { final userData = userDoc.data() as Map<String, dynamic>; return Scaffold( appBar: AppBar( title: const Text('主页'), actions: [ IconButton( icon: const Icon(Icons.logout), onPressed: () async { await FirebaseAuth.instance.signOut(); }, ), ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('姓名: ${userData['name']}', style: const TextStyle(fontSize: 18)), const SizedBox(height: 10), Text('邮箱: ${userData['email']}', style: const TextStyle(fontSize: 18)), const SizedBox(height: 10), Text('地址: ${userData['address']}', style: const TextStyle(fontSize: 18)), const SizedBox(height: 10), Text('电话: ${userData['phone']}', style: const TextStyle(fontSize: 18)), ], ), ), ); } }
5. 配置Firestore安全规则
在Firebase控制台设置规则,确保用户只能访问自己的数据:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
核心逻辑说明
- UID自动关联: 用
FirebaseAuth.currentUser.uid作为Firestore文档ID,实现认证与用户数据的自动绑定,无需手动操作。 - 首次登录判断: 通过检查Firestore中是否存在对应UID的文档,自动引导新用户完善信息。
- 数据安全: 借助Firestore规则限制用户权限,避免数据泄露。
内容的提问来源于stack exchange,提问作者Muhammad Zunair Shahzad
相关产品推荐
相关产品推荐

