Flutter中try-catch无法捕获Firebase Auth错误致应用崩溃
Firebase Auth密码重置页面:崩溃与热重载问题修复
问题1:无效邮箱导致应用崩溃,try-catch未生效
你的代码仅捕获了FirebaseAuthException,但邮箱格式错误时Firebase抛出的是PlatformException,导致异常漏捕引发崩溃。同时建议提前做输入校验,减少无效请求。
修复步骤:
- 扩展catch块,同时捕获
PlatformException及通用异常 - 封装统一弹窗方法,减少重复代码
- 添加邮箱格式与非空校验,提前拦截无效输入
修改后的核心代码:
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
相关产品推荐
相关产品推荐

