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

Flutter应用构建抛出NotInitializedError,请求调试帮助

构建MyApp组件时抛出NotInitializedError的调试方案

问题场景

在VSCode开发Flutter应用时,构建MyApp组件抛出NotInitializedError,需调试解决。

错误信息

══╡ 组件库捕获异常 ╞═══════════════════════════════════════════════════════════
构建MyApp(dirty)时抛出以下NotInitializedError:
Instance of 'NotInitializedError'

相关错误触发组件:
MyApp MyApp:file:///C:/Users/abuls/Desktop/ADHD_TASK_MANAGER/lib/main.dart:34:18

完整代码

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/foundation.dart';

import '/screens/login_screen.dart';
import '/screens/home_screen.dart';
import '/screens/register_screen.dart';
import '/screens/advice_screen.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  try {
    // Load .env file for non-web platforms
    if (!kIsWeb) {
      await dotenv.load(fileName: ".env");
      // Check if the variable is loaded
      String? openAiKey = dotenv.env['OPENAI_API_KEY'];
      print('Dotenv Loaded: OPENAI_API_KEY = $openAiKey');
    } else {
      print("Running on Web. Skipping dotenv load.");
    }

    // Initialize Firebase
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
    print("Firebase initialized successfully.");

    // Run the app once Firebase is initialized
    runApp(const MyApp());
  } catch (e) {
    print("Error during Firebase initialization: $e");
    runApp(const MyAppWithError()); // Show an error screen if Firebase fails to initialize
  }
}

// Error screen to show if Firebase initialization fails
class MyAppWithError extends StatelessWidget {
  const MyAppWithError({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Task Manager',
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Text(
            'Error initializing Firebase. Please try again later.',
            style: TextStyle(fontSize: 18, color: Colors.red),
          ),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    String? openAiKey = dotenv.env['OPENAI_API_KEY'];
    print('OPENAI_API_KEY in MaterialApp: $openAiKey');

    return MaterialApp(
      title: 'Task Manager',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        scaffoldBackgroundColor: const Color(0xFFEFF2FB),
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFFB8C0FF),
          primary: const Color(0xFFB8C0FF),
          secondary: const Color(0xFFB8E0FF),
        ),
        inputDecorationTheme: InputDecorationTheme(
          filled: true,
          fillColor: Colors.white,
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(12),
          ),
          focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Colors.blue.shade200, width: 2),
            borderRadius: BorderRadius.circular(12),
          ),
          enabledBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Colors.blue.shade100, width: 1),
            borderRadius: BorderRadius.circular(12),
          ),
        ),
        textTheme: const TextTheme(
          titleLarge: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          bodyMedium: TextStyle(fontSize: 16),
        ),
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color(0xFFB8E0FF),
            foregroundColor: Colors.black,
            padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 24),
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
            textStyle: const TextStyle(fontWeight: FontWeight.bold),
          ),
        ),
        textButtonTheme: TextButtonThemeData(
          style: TextButton.styleFrom(
            foregroundColor: const Color(0xFF6C63FF),
            textStyle: const TextStyle(decoration: TextDecoration.underline),
          ),
        ),
      ),
      home: const AuthWrapper(),
      routes: {
        '/register': (context) => const RegisterScreen(),
        '/home': (context) => const HomeScreen(),
        '/login': (context) => const LoginScreen(),
        '/advice': (context) => const AdviceScreen(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        // Show loading indicator while waiting for auth state
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Scaffold(
            body: Center(child: CircularProgressIndicator()),
          );
        }

        // Show error message if there's an error with the authentication stream
        if (snapshot.hasError) {
          return const Scaffold(
            body: Center(child: Text("Error loading user state")),
          );
        }

        // Navigate to HomeScreen if user is authenticated, else to LoginScreen
        return snapshot.hasData ? const HomeScreen() : const LoginScreen();
      },
    );
  }
}

问题根源

代码仅在非Web平台加载dotenv,但MyApp的build方法无论平台都直接调用dotenv.env['OPENAI_API_KEY']。Web平台下dotenv未初始化,访问时抛出NotInitializedError。

修复方案

方案一:按平台判断访问dotenv

修改MyApp的build方法,仅在非Web平台访问dotenv,Web平台单独处理:

@override
Widget build(BuildContext context) {
  String? openAiKey;
  if (!kIsWeb) {
    openAiKey = dotenv.env['OPENAI_API_KEY'];
  } else {
    // Web平台可通过环境变量注入等方式获取密钥,示例:
    // openAiKey = const String.fromEnvironment('OPENAI_API_KEY');
    print("Web平台跳过dotenv访问");
  }
  print('OPENAI_API_KEY in MaterialApp: $openAiKey');
  
  // 剩余代码保持不变
}

方案二:Web平台也初始化dotenv

若需要在Web平台使用dotenv,修改main函数去掉平台判断,同时确保Web端配置正确:

try {
  // 为所有平台加载.env文件
  await dotenv.load(fileName: ".env");
  String? openAiKey = dotenv.env['OPENAI_API_KEY'];
  print('Dotenv Loaded: OPENAI_API_KEY = $openAiKey');
} catch (e) {
  print("加载dotenv失败: $e");
}

注意:Web平台使用dotenv需额外配置,比如在web/index.html中注入环境变量,或确保pubspec.yaml中依赖配置正确。

额外检查

确认Firebase初始化逻辑正常,当前代码已在初始化完成后运行MyApp,无需调整;AuthWrapper中使用FirebaseAuth的逻辑依赖Firebase初始化完成,当前流程已满足要求。

内容的提问来源于stack exchange,提问作者M.Shaher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:04:59