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

Flutter登录异常时SnackBar无法显示的问题求助

问题:登录错误时SnackBar不显示

我在独立Dart文件中封装了SnackBar的ErrorAlert组件,在登录方法的异常捕获块中传入context和错误信息调用该组件,但触发登录错误(如邮箱格式错误)时,SnackBar并未显示。

组件代码

import 'package:flutter/material.dart';
import 'package:app/globals.dart' as globals;

class ErrorAlert{

  showAlert(context, message) {
    return ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        backgroundColor: globals.mainColor,
        content: Text(message),
        duration: const Duration(seconds: 5),
        action: SnackBarAction(
          label: 'Dismiss',
          textColor: Colors.white,
          onPressed: () {
            ScaffoldMessenger.of(context).hideCurrentSnackBar();
          },
        ),
      )

    );
  }

}

登录方法代码

signInWithEmailIdAndPassword(email,password, context) async {
    try {
      UserCredential result = await fireAuth.signInWithEmailAndPassword(email: email, password: password);
      User user = result.user!;
      // checkUser = user; //returns UserID
      if(result != null) {
        Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => const HomeScreen()));
      }
    }
    catch(signError) {
      if(signError is PlatformException) {
        if(signError.code == 'ERROR_WRONG_PASSWORD') {
          ErrorAlert().showAlert(context, 'Wrong Password!');
        } else if(signError.code == 'ERROR_INVALID_EMAIL') {
          ErrorAlert().showAlert(context, 'Invalid Email ID!');
        } else if(signError.code == 'ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL') {
          ErrorAlert().showAlert(context, 'Account is already exists with different credentials!');
        } else if(signError.code == 'ERROR_USER_NOT_FOUND') {
          ErrorAlert().showAlert(context, 'User not found!');
        }
        print(signError);
      }
    }
    // return checkUser;
  }

控制台日志

E/RecaptchaCallWrapper(32567): Initial task failed for action RecaptchaAction(action=signInWithPassword)with exception - The email address is badly formatted.

解决方案

1. 修正异常类型判断

当前代码捕获的是PlatformException,但Firebase Auth最新版本抛出的是FirebaseAuthException,导致异常没进入判断分支,SnackBar自然不会触发。同时Firebase的错误码已更新,比如原ERROR_INVALID_EMAIL现在是invalid-email,需要同步修改:

修改后的登录方法异常捕获部分:

catch(signError) {
  if(signError is FirebaseAuthException) {
    switch(signError.code) {
      case 'wrong-password':
        ErrorAlert().showAlert(context, '密码错误!');
        break;
      case 'invalid-email':
        ErrorAlert().showAlert(context, '邮箱格式无效!');
        break;
      case 'account-exists-with-different-credential':
        ErrorAlert().showAlert(context, '该邮箱已绑定其他登录方式!');
        break;
      case 'user-not-found':
        ErrorAlert().showAlert(context, '用户不存在!');
        break;
      default:
        ErrorAlert().showAlert(context, signError.message ?? '登录失败,请稍后重试');
    }
    print(signError);
  } else {
    // 处理其他类型异常
    ErrorAlert().showAlert(context, '登录失败,请稍后重试');
  }
}

注意需要导入firebase_auth包:import 'package:firebase_auth/firebase_auth.dart';

2. 确保Context有效性

如果调用登录方法的context不是当前页面Scaffold的上下文(比如直接用MaterialApp的context),ScaffoldMessenger找不到对应的Scaffold,SnackBar也无法显示。解决方法:

  • 在登录按钮外层套一个Builder组件,用Builder的context传入登录方法:
Builder(
  builder: (ctx) {
    return ElevatedButton(
      onPressed: () => signInWithEmailIdAndPassword(email, password, ctx),
      child: const Text('登录'),
    );
  },
)
  • 或者使用全局ScaffoldMessengerKey,无需传context更方便:
    1. 在全局文件(比如globals.dart)中定义:
    final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
    
    1. 在MaterialApp中配置:
    MaterialApp(
      scaffoldMessengerKey: scaffoldMessengerKey,
      // ...其他配置
    )
    
    1. 修改ErrorAlert组件:
    class ErrorAlert{
      static showAlert(String message) {
        return globals.scaffoldMessengerKey.currentState?.showSnackBar(
          SnackBar(
            backgroundColor: globals.mainColor,
            content: Text(message),
            duration: const Duration(seconds: 5),
            action: SnackBarAction(
              label: '关闭',
              textColor: Colors.white,
              onPressed: () {
                globals.scaffoldMessengerKey.currentState?.hideCurrentSnackBar();
              },
            ),
          )
        );
      }
    }
    
    1. 调用时无需传context:
    ErrorAlert.showAlert('邮箱格式无效!');
    

3. 额外检查

  • 确认globals.mainColor是可见的颜色,避免SnackBar背景色和内容色接近导致看不见
  • 确保登录方法执行时,当前页面还未被Navigator跳转(异常发生时不会执行Navigator.pushReplacement)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:37:17