Flutter Navigator.of(context).pushReplacementNamed 抛出:“未处理的异常:在 main.dart 上使用空值检查运算符”

Jeo*_*oxs 3 dart firebase flutter

因此,我开始使用 sdk: ">=2.16.2 <3.0.0" 和 Firebase 集成制作一个 Flutter 应用程序。我在 main.dart 上有以下“authStateChanges()”代码:

if (snapshot.connectionState == ConnectionState.done) {
   FirebaseAuth.instance.authStateChanges().listen((User? user) {
      if (user == null) {
         Navigator.of(context).pushReplacementNamed('login');
      } else {
         Navigator.of(context).pushReplacementNamed('home');
      }
   });
}
Run Code Online (Sandbox Code Playgroud)

它在加载应用程序时第一次工作,但如果用户登录(或退出),则导航器上会出现“未处理的异常:空值检查运算符”。

发生FLutter异常

这是完整的 main.dart 代码:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:pollux_android/src/pages/error_page.dart';
import 'package:pollux_android/src/pages/loading_page.dart';
import 'package:pollux_android/src/routes/routes.dart';

void main() {
  runApp(MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
}

class _MyAppState extends State<MyApp> {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      routes: polluxRoutes,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: mainScreen(),
    );
  }

  mainScreen() {
    return FutureBuilder(
      future: _initialization,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return const ErrorPage(
            errorMessage: 'Unknown error',
          );
        }

        if (snapshot.connectionState == ConnectionState.done) {
          FirebaseAuth.instance.authStateChanges().listen((User? user) {
            if (user == null) {
              Navigator.of(context).pushReplacementNamed('login');
            } else {
              Navigator.of(context).pushReplacementNamed('home');
            }
          });
        }

        return const LoadingPage();
      },
    );
  }
}

Run Code Online (Sandbox Code Playgroud)

我不明白为什么它无法在 authStateChanges() 上第二次导航。感谢您提供的帮助。我相信这与新版本的 Null 检查有关,因为这个问题在 sdk 2.7.0 上没有发生

Jeo*_*oxs 5

由于某种原因,当 authStateChanges() 发生时,上下文变为 null。感谢@Saitoh-Akira,我想到了使用导航键并使用它在没有上下文的情况下进行导航。如果我理解正确的话,导航器需要一个状态。无论如何,添加导航键并使用它效果很好:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:pollux_android/src/pages/error_page.dart';
import 'package:pollux_android/src/pages/loading_page.dart';
import 'package:pollux_android/src/routes/routes.dart';

void main() {
  runApp(MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
  // final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
}

class _MyAppState extends State<MyApp> {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      routes: polluxRoutes,
      navigatorKey: navigatorKey,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: mainScreen(),
    );
  }

  mainScreen() {
    return FutureBuilder(
      future: _initialization,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return const ErrorPage(
            errorMessage: 'Some unknown error happened',
          );
        }

        if (snapshot.connectionState == ConnectionState.done) {
          FirebaseAuth.instance.authStateChanges().listen((User? user) {
            if (user == null) {
              navigatorKey.currentState?.pushNamedAndRemoveUntil('login', (route) => false);
            } else {
              navigatorKey.currentState?.pushNamedAndRemoveUntil('home', (route) => false);
            }
          });
        }

        return const LoadingPage();
      },
    );
  }
}

Run Code Online (Sandbox Code Playgroud)