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

Flutter使用GetStorage时出现空值检查运算符错误,求解决方案

问题描述

在Flutter项目中结合GetStorage与Firebase Auth判断用户登录状态时,未登录会触发“Null Check Operator Used On a Null Value”错误,登录后运行正常。以下是Home页面代码:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:mobihub_2/Screens/main_login.dart';
import 'package:mobihub_2/Screens/navigationscreens.dart/add.dart';

import 'navigationscreens.dart/adds.dart';
import 'navigationscreens.dart/chat.dart';
import 'navigationscreens.dart/home2.dart';
import 'navigationscreens.dart/person.dart';

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override

  // ignore: library_private_types_in_public_api
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final auth = FirebaseAuth.instance;

  int currentTab = 0;
  final List<Widget> screens = const [
    Home2(),
    Chat(),
    Youradds(),
    Account(),
  ];
  final PageStorageBucket bucket = PageStorageBucket();
  Widget currentScreen = const Home2();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey.shade100,
      body: PageStorage(
        bucket: bucket,
        child: currentScreen,
      ),
      floatingActionButton: FloatingActionButton(
        backgroundColor: const Color(0xFFFFDC3D),
        elevation: 2.5,
        onPressed: () {
          if(FirebaseAuth.instance.currentUser != null){
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => const AddItems()));
          }else{
            Navigator.push(context,
                MaterialPageRoute(builder: (context) =>  MainLogin()));
          }

        },
        child: const Icon(
          Icons.add,
          color: Colors.black,
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomAppBar(
        color: Colors.white,
        shape: const CircularNotchedRectangle(),
        notchMargin: 10,
        child: SizedBox(
          height: 60,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  MaterialButton(
                    highlightElevation: 0.0,
                    highlightColor: Colors.white,
                    hoverColor: Colors.white,
                    hoverElevation: 0.0,
                    minWidth: 40,
                    onPressed: () {
                      setState(() {
                        currentScreen = const Home2();
                        currentTab = 0;

                      });
                    },
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(
                          Icons.home,
                          color: currentTab == 0
                              ? const Color(0xFFFFDC3D)
                              : Colors.black,
                          size: 25,
                        ),
                        Text(
                          '',
                          style: TextStyle(
                              color: currentTab == 0
                                  ? const Color(0xFFFFDC3D)
                                  : Colors.white),
                        )
                      ],
                    ),
                  ),
                  MaterialButton(
                    highlightElevation: 0.0,
                    highlightColor: Colors.white,
                    hoverColor: Colors.white,
                    hoverElevation: 0.0,
                    minWidth: 40,
                    onPressed: () {
                      setState(() {
                        if(FirebaseAuth.instance.currentUser != null){
                          currentScreen = const Chat();
                          currentTab = 1;
                        }else{
                          Navigator.push(context,
                              MaterialPageRoute(builder: (context) =>  MainLogin()));
                        }

                      });
                    },
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(
                          Icons.chat,
                          color: currentTab == 1
                              ? const Color(0xFFFFDC3D)
                              : Colors.black,
                          size: 25,
                        ),
                        Text(
                          '',
                          style: TextStyle(
                              color: currentTab == 1
                                  ? const Color(0xFFFFDC3D)
                                  : Colors.white),
                        )
                      ],
                    ),
                  )
                ],
              ),
              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  MaterialButton(
                    highlightElevation: 0.0,
                    highlightColor: Colors.white,
                    hoverColor: Colors.white,
                    hoverElevation: 0.0,
                    minWidth: 40,
                    onPressed: () {
                      setState(() {
                        if(FirebaseAuth.instance.currentUser != null){
                          currentScreen = const Youradds();
                          currentTab = 2;
                        }else{
                          Navigator.push(context,
                              MaterialPageRoute(builder: (context) =>  MainLogin()));
                        }

                      });
                    },
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(
                          Icons.favorite,
                          color: currentTab == 2
                              ? const Color(0xFFFFDC3D)
                              : Colors.black,
                          size: 25,
                        ),
                        Text(
                          '',
                          style: TextStyle(
                              color: currentTab == 2
                                  ? const Color(0xFFFFDC3D)
                                  : Colors.white),
                        )
                      ],
                    ),
                  ),
                  MaterialButton(
                    highlightElevation: 0.0,
                    highlightColor: Colors.white,
                    hoverColor: Colors.white,
                    hoverElevation: 0.0,
                    autofocus: false,
                    minWidth: 40,
                    onPressed: () {
                      setState(() {
                        if(FirebaseAuth.instance.currentUser != null){
                          currentScreen =  Account();
                          currentTab = 3;
                        }else{
                          Navigator.push(context,
                              MaterialPageRoute(builder: (context) =>  MainLogin()));
                        }

                      });
                    },
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(
                          Icons.person,
                          color: currentTab == 3
                              ? const Color(0xFFFFDC3D)
                              : Colors.black,
                          size: 25,
                        ),
                        Text(
                          '',
                          style: TextStyle(
                              color: currentTab == 3
                                  ? const Color(0xFFFFDC3D)
                                  : Colors.white),
                        )
                      ],
                    ),
                  )
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}
问题根源

代码中List<Widget> screens在初始化阶段就创建了Chat、Youradds、Account这些组件,而这些组件内部大概率直接使用了FirebaseAuth.instance.currentUser!这类空断言操作符。未登录时currentUser为null,断言操作触发空检查错误。

解决办法

1. 延迟创建需要登录的页面组件

将固定的组件列表改为组件构建函数列表,仅在用户登录后才创建对应组件:

// 替换原有的screens列表
final List<Widget Function()> screenBuilders = [
  () => const Home2(),
  () => const Chat(),
  () => const Youradds(),
  () => Account(),
];

修改按钮点击逻辑,登录后再构建组件:

// 以Chat按钮为例
onPressed: () {
  setState(() {
    final user = FirebaseAuth.instance.currentUser;
    if(user != null){
      currentScreen = screenBuilders[1]();
      currentTab = 1;
    }else{
      Navigator.push(context, MaterialPageRoute(builder: (context) => const MainLogin()));
    }
  });
},

2. 修复子组件的空安全问题

检查Chat、Youradds、Account页面中所有使用currentUser!的地方,替换为安全的空处理方式:

  • 使用可选链?:FirebaseAuth.instance.currentUser?.uid
  • 使用默认值??:FirebaseAuth.instance.currentUser?.displayName ?? "匿名用户"
  • 用FutureBuilder/StreamBuilder监听用户状态:
// Account页面示例
class Account extends StatelessWidget {
  const Account({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<User?>(
      future: FirebaseAuth.instance.authStateChanges().first,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const CircularProgressIndicator();
        }
        if (snapshot.data == null) {
          return const Center(child: Text("请先登录"));
        }
        return Column(
          children: [
            Text("用户ID: ${snapshot.data!.uid}"),
            // 其他用户信息组件
          ],
        );
      },
    );
  }
}

3. 全局统一处理登录状态(优化)

在App入口用StreamBuilder监听authStateChanges(),直接根据登录状态跳转页面,避免未登录时加载Home页面:

// main.dart示例
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StreamBuilder<User?>(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          return snapshot.data != null ? const Home() : const MainLogin();
        },
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:50:28