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

Flutter中try-catch无法捕获Firebase Auth错误致应用崩溃

Firebase Auth密码重置页面:崩溃与热重载问题修复

问题1:无效邮箱导致应用崩溃,try-catch未生效

你的代码仅捕获了FirebaseAuthException,但邮箱格式错误时Firebase抛出的是PlatformException,导致异常漏捕引发崩溃。同时建议提前做输入校验,减少无效请求。

修复步骤:

  1. 扩展catch块,同时捕获PlatformException及通用异常
  2. 封装统一弹窗方法,减少重复代码
  3. 添加邮箱格式与非空校验,提前拦截无效输入

修改后的核心代码:

void _showErrorAlert(String message) {
  if (Platform.isIOS) {
    _showIOSAlert(context, Text(message));
  } else {
    _showAndroidAlert(context, Text(message));
  }
}

bool isValidEmail(String email) {
  return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
}

Future passwordReset() async {
  String resetMail = _emailController.text.trim();

  // 提前校验输入
  if (resetMail.isEmpty) {
    _showErrorAlert("Lütfen e-posta adresinizi girin");
    return;
  }
  if (!isValidEmail(resetMail)) {
    _showErrorAlert("Geçersiz e-posta formatı");
    return;
  }

  try {
    await FirebaseAuth.instance.sendPasswordResetEmail(email: resetMail);
    _showErrorAlert('$resetMail adresine şifre sıfırlama linki gönderildi');
  } on FirebaseAuthException catch (e) {
    _showErrorAlert(e.message ?? "Bir hata oluştu");
  } on PlatformException catch (e) {
    _showErrorAlert(e.message ?? "Bir hata oluştu");
  } catch (e) {
    _showErrorAlert("Beklenmedik bir hata oluştu");
  }
}

问题2:终端运行后VSCode热重载/重启失效

这是因为终端启动的Flutter进程未关联VSCode调试会话,解决方法:

  • 直接在VSCode中按F5启动调试,替代终端执行flutter run
  • 若已用终端启动,可在VSCode「运行和调试」面板选择「附加到进程」,找到对应Flutter进程关联后即可正常使用热功能

完整修复后代码

// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:petinonedemo/main.dart';

class ForgotPasswordPage extends StatefulWidget {
  const ForgotPasswordPage({super.key});

  @override
  State<ForgotPasswordPage> createState() => _ForgotPasswordPageState();
}

class _ForgotPasswordPageState extends State<ForgotPasswordPage> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _phoneNumberController = TextEditingController();

  @override
  void dispose() {
    _emailController.dispose();
    _phoneNumberController.dispose();
    super.dispose();
  }

  void _showIOSAlert(BuildContext context, Text myContent) {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => CupertinoAlertDialog(
        content: myContent,
        actions: <CupertinoDialogAction>[
          CupertinoDialogAction(
            isDefaultAction: true,
            onPressed: () {
              Navigator.pop(context);
            },
            child: const Text('Geri dön'),
          ),
        ],
      ),
    );
  }

  void _showAndroidAlert(BuildContext context, Text myContent) {
    showDialog(
      context: context,
      barrierDismissible: true,
      builder: (BuildContext context) {
        return AlertDialog(
          content: myContent,
          actions: <Widget>[
            TextButton(
              child: const Text("Geri dön"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  void _showErrorAlert(String message) {
    if (Platform.isIOS) {
      _showIOSAlert(context, Text(message));
    } else {
      _showAndroidAlert(context, Text(message));
    }
  }

  bool isValidEmail(String email) {
    return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
  }

  Future passwordReset() async {
    String resetMail = _emailController.text.trim();

    if (resetMail.isEmpty) {
      _showErrorAlert("Lütfen e-posta adresinizi girin");
      return;
    }

    if (!isValidEmail(resetMail)) {
      _showErrorAlert("Geçersiz e-posta formatı");
      return;
    }

    try {
      await FirebaseAuth.instance.sendPasswordResetEmail(email: resetMail);
      _showErrorAlert('$resetMail adresine şifre sıfırlama linki gönderildi');
    } on FirebaseAuthException catch (e) {
      _showErrorAlert(e.message ?? "Bir hata oluştu");
    } on PlatformException catch (e) {
      _showErrorAlert(e.message ?? "Bir hata oluştu");
    } catch (e) {
      _showErrorAlert("Beklenmedik bir hata oluştu");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Şifremi Unuttum"),
        elevation: 0,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                height: 70,
                padding: const EdgeInsets.symmetric(horizontal: 25),
                child: TextField(
                    controller: _emailController,
                    cursorColor: Colors.white,
                    keyboardType: TextInputType.emailAddress,
                    style: const TextStyle(color: Colors.white),
                    decoration: InputDecoration(
                        floatingLabelBehavior: FloatingLabelBehavior.never,
                        hintText: "E-posta",
                        hintStyle: const TextStyle(color: Colors.white),
                        labelStyle: const TextStyle(color: Colors.white),
                        filled: true,
                        fillColor: applicationPurple,
                        border: OutlineInputBorder(
                            borderSide: BorderSide.none,
                            borderRadius: BorderRadius.circular(20)))),
              ),
              Container(
                decoration: BoxDecoration(
                    color: applicationOrange,
                    borderRadius: BorderRadius.circular(20)),
                height: 50,
                padding: const EdgeInsets.symmetric(horizontal: 25.0),
                child: TextButton(
                  onPressed: passwordReset,
                  child: const Text(
                    "Şifremi Sıfırla",
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Ata Berk Çinetçi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:24:57