You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中实现Firebase Auth注册用户UID与Cloud Firestore关联的方案

如何在Firebase Auth注册时将UID同步为Firestore文档ID

我刚好解决了和你一模一样的需求!当用户通过邮箱密码完成Firebase Auth注册后,把自动生成的UID作为Cloud Firestore中users集合的文档ID创建空文档,后续让用户在主应用内补充完善其他数据。下面是我亲测可行的实现方案:

实现步骤

1. 封装Firestore操作类

先创建一个adduser.dart文件,专门用来处理Firestore的用户数据操作。这里定义DatabaseService类,通过构造函数传入用户UID,这样就能精准定位到对应用户的文档:

import 'package:cloud_firestore/cloud_firestore.dart';
FirebaseFirestore firestore = FirebaseFirestore.instance;
class DatabaseService {
  final String uid;
  DatabaseService({ required this.uid });
  // 引用users集合
  final CollectionReference userCollection = FirebaseFirestore.instance.collection('users');
  // 初始化用户数据(传空值是为了先创建文档,后续再补充内容)
  Future updateUserData(String ouderName, String kindName, String school,) async {
    return await userCollection.doc(uid).set({
      'ouderName' : ouderName,
      'kindName' : kindName,
      'school' : school,
    });
  }
}

2. 在注册流程中触发文档创建

找到你的Firebase Auth注册逻辑所在的fire_auth.dart文件,在注册成功返回用户对象之前,调用上面的updateUserData方法,传入空字符串就能创建以UID为ID的文档:

// 在return user;之前添加这行代码
await DatabaseService(uid: user!.uid).updateUserData('', '', '');

完成这一步后,用户注册成功的同时,Firestore的users集合里就会生成一个以该用户UID为文档ID的空结构文档,后续用户进入主应用后,你可以通过同样的DatabaseService类来更新这个文档的内容。

附:完整的注册页面代码

这里是我使用的注册页面实现,供你参考:

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:planplay/login/profile_page.dart';
import 'package:planplay/login/fire_auth.dart';
import 'package:planplay/login/validator.dart';

class RegisterPage extends StatefulWidget {
  @override
  _RegisterPageState createState() => _RegisterPageState();
}

class _RegisterPageState extends State<RegisterPage> {
  final _registerFormKey = GlobalKey<FormState>();
  final _nameTextController = TextEditingController();
  final _emailTextController = TextEditingController();
  final _passwordTextController = TextEditingController();

  final _focusName = FocusNode();
  final _focusEmail = FocusNode();
  final _focusPassword = FocusNode();

  bool _isProcessing = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        _focusName.unfocus();
        _focusEmail.unfocus();
        _focusPassword.unfocus();
      },
      child: Scaffold(
        appBar: AppBar(
          iconTheme: IconThemeData(color: Color.fromRGBO(132, 76, 130, 1)),
          title: Text('Registreren', style: TextStyle(color: Color.fromRGBO(132, 76, 130, 1))),
          centerTitle: true,
          backgroundColor: Color.fromRGBO(250, 202, 48, 1),
        ),
        body: Center(
          child: SingleChildScrollView(
            reverse: true,
            padding: EdgeInsets.all(32),
            child: Padding(
              padding: const EdgeInsets.all(24.0),
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      height: 120.0,
                      width: 120.0,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage(
                              'assets/images/logo.jpg'), fit: BoxFit.fill,
                        ),
                      ),
                    ),
                    SizedBox(height: 24.0),
                    Form(
                      key: _registerFormKey,
                      child: Column(
                        children: <Widget>[
                          TextFormField(
                            controller: _nameTextController,
                            focusNode: _focusName,
                            validator: (value) => Validator.validateName(
                              name: value,
                            ),
                            decoration: InputDecoration(
                              enabledBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color:Color.fromRGBO(132, 76, 130, 1))),
                              hintText: "Naam ouder",
                              hintStyle: TextStyle(color: Color.fromRGBO(132, 76, 130, 1)),
                              focusedBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color: Color.fromRGBO(250, 202, 48, 1))),
                              errorBorder: UnderlineInputBorder(
                                borderRadius: BorderRadius.circular(6.0),
                                borderSide: BorderSide(
                                  color: Colors.red,
                                ),
                              ),
                            ),
                          ),
                          SizedBox(height: 16.0),
                          TextFormField(
                            controller: _emailTextController,
                            focusNode: _focusEmail,
                            validator: (value) => Validator.validateEmail(
                              email: value,
                            ),
                            decoration: InputDecoration(
                              enabledBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color:Color.fromRGBO(132, 76, 130, 1))),
                              hintText: "Email adres",
                              hintStyle: TextStyle(color: Color.fromRGBO(132, 76, 130, 1)),
                              focusedBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color: Color.fromRGBO(250, 202, 48, 1))),
                              errorBorder: UnderlineInputBorder(
                                borderRadius: BorderRadius.circular(6.0),
                                borderSide: BorderSide(
                                  color: Colors.red,
                                ),
                              ),
                            ),
                          ),
                          SizedBox(height: 16.0),
                          TextFormField(
                            controller: _passwordTextController,
                            focusNode: _focusPassword,
                            obscureText: true,
                            validator: (value) => Validator.validatePassword(
                              password: value,
                            ),
                            decoration: InputDecoration(
                              enabledBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color:Color.fromRGBO(132, 76, 130, 1))),
                              hintText: "Wachtwoord",
                              hintStyle: TextStyle(color: Color.fromRGBO(132, 76, 130, 1)),
                              focusedBorder: UnderlineInputBorder(
                                  borderSide: BorderSide(color: Color.fromRGBO(250, 202, 48, 1))),
                              errorBorder: UnderlineInputBorder(
                                borderRadius: BorderRadius.circular(6.0),
                                borderSide: BorderSide(
                                  color: Colors.red,
                                ),
                              ),
                            ),
                          ),
                          SizedBox(height: 32.0),
                          _isProcessing ? CircularProgressIndicator(
                            valueColor: AlwaysStoppedAnimation<Color>(Color.fromRGBO(250, 202, 48, 1)),
                          ) : Row(
                            children: [
                              Expanded(
                                child: ElevatedButton(
                                  onPressed: () async {
                                    setState(() {
                                      _isProcessing = true;
                                    });

                                    if (_registerFormKey.currentState!
                                        .validate()) {
                                      User? user = await FireAuth
                                          .registerUsingEmailPassword(
                                        name: _nameTextController.text,
                                        email: _emailTextController.text,
                                        password: _passwordTextController.text,
                                      );

                                      setState(() {
                                        _isProcessing = false;
                                      });

                                      if (user != null) {
                                        Navigator.of(context)
                                            .pushAndRemoveUntil(
                                          MaterialPageRoute(
                                            builder: (context) => ProfilePage(user: user),
                                          ),
                                              ModalRoute.withName('/'),
                                        );
                                      }
                                    } else {
                                      final snackBar = SnackBar(content: Row(
                                        mainAxisAlignment: MainAxisAlignment.start,
                                        children: [
                                          Icon(Icons.error_outline, size: 32, color:Color.fromRGBO(132, 76, 130, 1)),
                                          const SizedBox(width: 16),
                                          Expanded(child: Text('Gegevens onjuist, vul de juiste gegevens in', style: TextStyle(color:Color.fromRGBO(132, 76, 130, 1))), ),
                                        ],
                                      ), backgroundColor: Colors.red, );
                                      ScaffoldMessenger.of(context).showSnackBar(snackBar);
                                      setState(() {
                                        _isProcessing = false;
                                      });
                                    }
                                  },
                                  child: Text(
                                    'Registreren',
                                    style: TextStyle(color: Color.fromRGBO(132, 76, 130, 1)),
                                  ),
                                  style: ButtonStyle(
                                    backgroundColor: MaterialStateProperty.all(Color.fromRGBO(250, 202, 48, 1)),
                                  ),
                                ),
                              ),
                            ],
                          )
                        ],
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Hagi Pro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:09:15