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

Flutter接入Firebase Auth时邮箱未注册/密码错误仍可登录问题排查

问题原因分析

你的认证逻辑核心问题是没有对Firebase Auth接口抛出的异常做捕获处理:
Firebase Auth的signInWithEmailAndPassword、createUserWithEmailAndPassword这类方法,在遇到邮箱未注册、密码错误、邮箱格式非法、账号被封禁等异常场景时,会主动抛出对应类型的FirebaseAuthException。你现有的代码完全没有做异常捕获,只要上层调用时没有等待异步执行完成、或者没有捕获抛出的异常,就会直接跳过错误分支,误判为登录成功。

修复方案

1. 改造认证方法,新增异常捕获逻辑

修改Authentication.dart中的logIntoAccount、createAccount方法,增加异常捕获分支,返回明确的执行结果:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';

class Authentication with ChangeNotifier {
  final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
  final GoogleSignIn googleSignIn = GoogleSignIn();

  String? userUid;
  String? get getUserUid => userUid;

  // 改造后的邮箱登录方法
  Future<Object> logIntoAccount(String email, String password) async {
    try {
      UserCredential userCredential = await firebaseAuth
          .signInWithEmailAndPassword(email: email, password: password);
      User? user = userCredential.user;
      if(user != null) {
        userUid = user.uid;
        debugPrint(userUid);
        notifyListeners();
        return true;
      }
      return "获取用户信息失败";
    } on FirebaseAuthException catch (e) {
      // 匹配不同错误码返回对应提示
      switch(e.code) {
        case 'user-not-found':
          return "该邮箱未注册";
        case 'wrong-password':
          return "输入的密码错误";
        case 'invalid-email':
          return "邮箱格式不合法";
        case 'user-disabled':
          return "该账号已被封禁";
        default:
          return "登录失败:${e.message}";
      }
    } catch (e) {
      return "未知错误:$e";
    }
  }

  // 改造后的账号注册方法
  Future<Object> createAccount(String email, String password) async {
    try {
      UserCredential userCredential = await firebaseAuth
          .createUserWithEmailAndPassword(email: email, password: password);
      User? user = userCredential.user;
      if(user != null) {
        userUid = user.uid;
        debugPrint('Created account Uid => $userUid');
        notifyListeners();
        return true;
      }
      return "获取用户信息失败";
    } on FirebaseAuthException catch (e) {
      switch(e.code) {
        case 'email-already-in-use':
          return "该邮箱已被注册";
        case 'invalid-email':
          return "邮箱格式不合法";
        case 'operation-not-allowed':
          return "邮箱登录功能未开启";
        case 'weak-password':
          return "密码强度过低";
        default:
          return "注册失败:${e.message}";
      }
    } catch (e) {
      return "未知错误:$e";
    }
  }

  Future logOutViaEmail() {
    userUid = null;
    notifyListeners();
    return firebaseAuth.signOut();
  }

  Future signInWithGoogle() async {
    final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn();
    if(googleSignInAccount == null) return "用户取消了Google登录";
    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;
    final AuthCredential authCredential = GoogleAuthProvider.credential(
        accessToken: googleSignInAuthentication.accessToken,
        idToken: googleSignInAuthentication.idToken);

    try {
      final UserCredential userCredential =
          await firebaseAuth.signInWithCredential(authCredential);
      final User? user = userCredential.user;
      if(user == null) return "获取Google用户信息失败";

      userUid = user.uid;
      debugPrint('Google User Uid => $userUid');
      notifyListeners();
      return true;
    } on FirebaseAuthException catch (e) {
      return "Google登录失败:${e.message}";
    }
  }

  Future signOutWithGoogle() async {
    userUid = null;
    notifyListeners();
    return googleSignIn.signOut();
  }
}

2. 上层调用注意事项

调用异步认证方法时必须添加await,等方法执行完成后再判断结果,禁止调用后直接走登录成功逻辑,示例如下:

// 错误写法:不等异步执行完成就跳转,不管成功失败都认为登录成功
auth.logIntoAccount(inputEmail, inputPassword);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage()));

// 正确写法:等待执行结果,判断成功后再跳转
var loginResult = await auth.logIntoAccount(inputEmail, inputPassword);
if(loginResult == true) {
  // 登录成功跳转首页
  if(mounted) {
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage()));
  }
} else {
  // 登录失败弹出错误提示
  if(mounted) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(loginResult.toString()))
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:15:03