Send OTP to Email using with Flutter & Firebase
Hello everyone,
In this article, I will give you information about Firebase authentication methods and the structure I have customized using Flutter and Firebase.
The article not includes about Firebase setup.
Keywords:
- Flutter: It is an open source framework that allows us to output as cross platform written in the Dart programming language developed by Google.
- Firebase: It is a cloud-based backend service offered by Google that includes tools such as database management, authentication, file storage, messaging, analysis, etc.
- OTP(One Time Password): It is one-time passwords used in the authentication process of users’ identity information.
What is the issue/case?
In applications, we need to verify the user in the user registration and forgot password sections. In custom written backend services, this operation is already managed by the backend. But if you are using Firebase…
You can manage this operation in two situations:
1- With Firebase Auth Methods on Browser
You can send user verification mail with “sendEmailVerification” or “sendPasswordResetEmail” methods in Firebase’s authentication system. When the link in the mail is clicked, you can carry out your transactions on the page opened in the browser.
A. User Verification
While the user is registering, you can send the email verification mail that the user has entered.
FirebaseAuth auth = FirebaseAuth.instance;
auth.createUserWithEmailAndPassword(email: "your-user-email", password: "your-user-password");
auth.currentUser.sendEmailVerification();
B. Password Reset
If the user forgot her/his password, you can send a password reset link to the user’s e-mail.
FirebaseAuth auth = FirebaseAuth.instance;
auth.sendPasswordResetEmail(email: "your-user-email");
The link automatically sent from Firebase to the user’s e-mail is as follows:
Clicking on the link opens a page in the browser for your user to set her/his new password as follows:
You can also follow your email template and operations (forwarding to your own site) from Firebase Create Custom Email Action Handlers.
I don’t find the first situation suitable for UX. Why would we want the user using the mobile application to renew the password in the web browser?
2- With Custom Operation on Mobile
While the user is registering, we also save her/his password to the firestore database. (It is healthier to encrypt the password and save it to the database.)
The purpose of saving the password is to enable the user to log in first and then update the password if the user enters OTP correctly.
FirebaseAuth auth = FirebaseAuth.instance;
auth.createUserWithEmailAndPassword(email: "your-user-email", password: "your-user-password");
String encryptedPassword = PasswordUtils.instance.encrypt("your-user-password"); // (PasswordUtils is a custom class)
FirebaseFirestore collection = FirebaseFirestore.instance.collection("your-path-name");
await collection.doc("user-id").set({'email': auth.currentUser.email!, 'password': encryptedPassword});
When the user sends a request to reset her/his password with her/his email, we save a data called OTP to the user information in the Firestore database. We also send this OTP to the user’s mail simultaneously using an email service.
FirebaseFirestore collection = FirebaseFirestore.instance.collection("your-path-name");
final snapshot = await collection.where('email', isEqualTo: "your-user-email").get();
if (snapshot.docs.isNotEmpty) {
var user = snapshot.docs.first;
int otp = 5468; // You can use a generator method
await collection.doc(user.id).update({'otpCode': otp});
// Use any email service to send email
EmailService.instance.sendOTPEmail("your-user-email", otp); // (EmailService is a custom class using the mailer package)
} else {
// Print your email invalid or user not found
}
If the user enters the correct OTP within the application, we direct the user to our password reset page to set her new password.
FirebaseFirestore collection = FirebaseFirestore.instance.collection("your-path-name");
final snapshot = await collection.where('email', isEqualTo: "your-user-email").get();
if (snapshot.docs.isNotEmpty) {
final user = snapshot.docs.first!;
if (user['otpCode'] == 5468) {
// Send user to create new password
} else {
// Print the code is wrong
}
} else {
// Print your email invalid or user not found
}
When the user enters her/his new password, we first log in to account with the email and password found in our Firestore database, and then we complete the user’s password reset process as in the real life scenario by using the firebase auth “updatePassword” method.
FirebaseFirestore collection = FirebaseFirestore.instance.collection("your-path-name");
final snapshot = await collection.where('email', isEqualTo: "your-user-email").get();
if (snapshot.docs.isNotEmpty) {
String email = snapshot.docs.first['email'];
String password = snapshot.docs.first['password'];
String cleanPassword = PasswordUtils.instance.decrypt(password);
FirebaseAuth auth = FirebaseAuth.instance;
await auth.signInWithEmailAndPassword(email: email, password: cleanPassword);
await auth.currentUser!.updatePassword(password);
// Update new password in Firestore too
Stirng newPassword = await PasswordUtils.instance.encrypt("your-user-new-password");
await collection.doc(auth.currentUser!.uid).update({'password': newPassword});
} else {
// Print your email invalid or user not found
}
After resetting the password, it is entirely up to you to send the user to the home or onboarding page.
I just showed the password reset part. Using this method, you can manage the operation you want.
Thank you for reading. I hope it was helpful and you enjoyed reading it.
Note: In this article, I have shared the code in pieces for easy understand of what I have told. In the real scenario, it will be more useful to manage these structures from the custom classes you have prepared.
Also, if there is a part that you think is missing or wrong in the explanation, we can meet in the comments. Thanks for your support right now.
Best regards,
Mete Coban.