I want to reset the forgot password inside app using flutter. I have email verification screen then I use to get an otp that verifies the email after email verification I want to move to new password screen which takes new password as input and resets the password.
How to achive this using firebase flutter?
Edit 21 July, 2025
Now you can also update password without sending verification email check out this reference in firebase doc.
Check this. you will get password reset email to the email address that is sent to firebase
firebase_exceptions.dart
import 'package:firebase_auth/firebase_auth.dart';
enum AuthStatus {
successful,
wrongPassword,
emailAlreadyExists,
invalidEmail,
weakPassword,
unknown,
}
class AuthExceptionHandler {
static handleAuthException(FirebaseAuthException e) {
AuthStatus status;
switch (e.code) {
case "invalid-email":
status = AuthStatus.invalidEmail;
break;
case "wrong-password":
status = AuthStatus.wrongPassword;
break;
case "weak-password":
status = AuthStatus.weakPassword;
break;
case "email-already-in-use":
status = AuthStatus.emailAlreadyExists;
break;
default:
status = AuthStatus.unknown;
}
return status;
}
static String generateErrorMessage(error) {
String errorMessage;
switch (error) {
case AuthStatus.invalidEmail:
errorMessage = "Your email address appears to be malformed.";
break;
case AuthStatus.weakPassword:
errorMessage = "Your password should be at least 6 characters.";
break;
case AuthStatus.wrongPassword:
errorMessage = "Your email or password is wrong.";
break;
case AuthStatus.emailAlreadyExists:
errorMessage =
"The email address is already in use by another account.";
break;
default:
errorMessage = "An error occured. Please try again later.";
}
return errorMessage;
}
}
reset_password.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:school/screens/firebase_exception.dart';
class ResetPasswordScreen extends StatefulWidget {
static const String id = 'reset_password';
const ResetPasswordScreen({Key? key}) : super(key: key);
@override
State<ResetPasswordScreen> createState() => _ResetPasswordScreenState();
}
class _ResetPasswordScreenState extends State<ResetPasswordScreen> {
final _key = GlobalKey<FormState>();
final _emailController = TextEditingController();
static final auth = FirebaseAuth.instance;
static late AuthStatus _status;
@override
void dispose() {
_emailController.dispose();
super.dispose();
}
Future<AuthStatus> resetPassword({required String email}) async {
await auth
.sendPasswordResetEmail(email: email)
.then((value) => _status = AuthStatus.successful)
.catchError(
(e) => _status = AuthExceptionHandler.handleAuthException(e));
return _status;
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: Container(
width: size.width,
height: size.height,
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
left: 16.0, right: 16.0, top: 50.0, bottom: 25.0),
child: Form(
key: _key,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () => Navigator.pop(context),
child: const Icon(Icons.close),
),
const SizedBox(height: 70),
const Text(
"Forgot Password",
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
const SizedBox(height: 10),
const Text(
'Please enter your email address to recover your password.',
style: TextStyle(
fontSize: 15,
color: Colors.black,
),
),
const SizedBox(height: 40),
const Text(
'Email address',
style: TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Container(
child: TextFormField(
obscureText: false,
controller: _emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Empty email';
}
return null;
},
autofocus: false,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: kDarkGrey),
decoration: const InputDecoration(
contentPadding:
EdgeInsets.symmetric(vertical: 20, horizontal: 20),
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(30.0))),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: kBlackText,
width: 1,
),
borderRadius: BorderRadius.all(
Radius.circular(
30.0,
),
),
),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: kSecondaryColor, width: 2.0),
borderRadius: BorderRadius.all(
Radius.circular(
30.0,
),
),
),
isDense: true,
// fillColor: kPrimaryColor,
filled: true,
errorStyle: TextStyle(fontSize: 15),
hintText: 'email address',
hintStyle: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: kLightWhiteGray),
),
),
),
const SizedBox(height: 16),
const Expanded(child: SizedBox()),
SizedBox(
height: MediaQuery.of(context).size.height / 20,
child: Material(
elevation: 2,
borderRadius: BorderRadius.circular(20),
color: kSecondaryColor,
child: MaterialButton(
onPressed: () async {
if (_key.currentState!.validate()) {
final _status = await resetPassword(
email: _emailController.text.trim());
if (_status == AuthStatus.successful) {
//your logic
} else {
//your logic or show snackBar with error message
}
}
},
minWidth: double.infinity,
child: const Text(
'RECOVER PASSWORD',
style: TextStyle(
color: kBlackText,
fontWeight: FontWeight.bold,
fontSize: 16,
fontFamily: 'Poppins'),
),
),
),
),
const SizedBox(height: 20),
],
),
),
),
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With