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

Flutter StreamBuilder触发空值错误,无法通过Doc()获取当前用户

问题解决:Firebase Auth空值异常处理方案

错误原因

触发的_CastError核心原因是:组件初始化阶段FirebaseAuth.instance.currentUser还未完成异步加载,处于null状态,直接用!强制非空就触发了空值检查异常。Firebase Auth的用户状态是异步获取的,StatefulWidget成员变量初始化时根本拿不到有效用户数据。

修复方案

不要在成员变量里硬编码用户ID,而是先监听Firebase Auth的用户状态流,确认用户已登录后,再请求Firestore的vendor数据。用嵌套StreamBuilder处理双层数据流:

class _LandingScreenState extends State<LandingScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 先监听Auth用户状态流
      body: StreamBuilder<User?>(
        stream: FirebaseAuth.instance.userChanges(),
        builder: (context, authSnapshot) {
          // Auth加载中
          if (authSnapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }

          // 用户未登录,跳转登录页
          if (authSnapshot.data == null) {
            return const LoginScreen();
          }

          // 用户已登录,获取当前用户ID,监听Firestore数据
          final currentUserId = authSnapshot.data!.uid;
          return StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
            stream: FirebaseFirestore.instance
                .collection('vendor')
                .doc(currentUserId)
                .snapshots(),
            builder: (context, firestoreSnapshot) {
              if (firestoreSnapshot.hasError) {
                return const Center(child: Text('Something went wrong'));
              }

              if (firestoreSnapshot.connectionState == ConnectionState.waiting) {
                return const Center(child: CircularProgressIndicator());
              }

              // vendor文档不存在,跳转注册页
              final vendorDoc = firestoreSnapshot.data;
              if (vendorDoc == null || !vendorDoc.exists) {
                return const RegistrationScreen();
              }

              // 解析vendor数据,处理空值安全
              final vendorData = vendorDoc.data();
              if (vendorData == null) {
                return const Center(child: Text('Invalid vendor data'));
              }
              final Vendor vendor = Vendor.fromJson(vendorData);

              // 已通过审核,跳转主页
              if (vendor.approved == true) {
                return const HomeScreen();
              }

              // 未通过审核,显示等待界面(处理logo空值)
              return Scaffold(
                body: Center(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Container(
                        height: 80,
                        width: 80,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(20),
                          child: vendor.logo != null
                              ? CachedNetworkImage(
                                  imageUrl: vendor.logo!,
                                  placeholder: (context, url) => Container(
                                    height: 80,
                                    width: 80,
                                    color: Colors.grey,
                                  ),
                                )
                              : Container(
                                  height: 80,
                                  width: 80,
                                  color: Colors.grey,
                                  child: const Icon(Icons.business),
                                ),
                        ),
                      ),
                      const Padding(
                        padding: EdgeInsets.all(15.0),
                        child: DecoratedBox(
                          decoration: BoxDecoration(
                            color: Colors.blue,
                            borderRadius: BorderRadius.all(Radius.circular(20)),
                          ),
                          child: Padding(
                            padding: EdgeInsets.all(20.0),
                            child: Text(
                              'Your application received!\nAdmin will contact you for a confirmation!',
                              textAlign: TextAlign.start,
                              style: TextStyle(
                                  fontSize: 25, fontWeight: FontWeight.normal),
                            ),
                          ),
                        ),
                      ),
                      const Padding(
                        padding: EdgeInsets.all(15.0),
                        child: DecoratedBox(
                          decoration: BoxDecoration(
                            color: Colors.teal,
                            borderRadius: BorderRadius.all(Radius.circular(50)),
                          ),
                          child: Padding(
                            padding: EdgeInsets.all(20.0),
                            child: Text(
                              'blah blah',
                              textAlign: TextAlign.start,
                              style: TextStyle(
                                  fontSize: 15, fontWeight: FontWeight.normal),
                            ),
                          ),
                        ),
                      ),
                      TextButton(
                        child: const Text('Sign Out'),
                        onPressed: () {
                          FirebaseAuth.instance.signOut().then((value) {
                            Navigator.of(context).pushReplacement(
                              MaterialPageRoute(
                                builder: (BuildContext context) =>
                                    const LoginScreen(),
                              ),
                            );
                          });
                        },
                      )
                    ],
                  ),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

关键优化点

  • 先通过userChanges()监听用户状态,确保拿到有效用户ID后再请求Firestore,彻底避免空值异常
  • 增加多层空值安全检查(Auth用户、Firestore文档、文档数据、logo字段),覆盖所有可能的空值场景
  • 统一加载状态处理逻辑,用户体验更一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:16:01