Part 1 of our series discussed the overall setup and user interface changes necessary for implementing an email verification in your Flutter app. In this part, we will focus on how to effectively configure the Simple Mail Transfer Protocol (SMTP) for email verification login. This step is crucial to ensure that the users receive the necessary verification links promptly and securely.
Overview of SMTP Mailer
SMTP is a standard protocol for sending emails across the Internet. By integrating an SMTP mailer into our application, we can automate the process of sending verification emails when users register. In this part of the blog, we will cover the following topics:
- Fetching Email Configuration: How to retrieve email configuration details from Firestore.
- Setting Up the SMTP Server: Configuring the SMTP server using the details fetched from Firestore.
- Creating and Sending the Email: Constructing the email message and sending it to the user’s email address.
Fetching Email Configuration for SMTP Setup
The first step in setting up the SMTP for email verification login is to fetch the email configuration details from Firestore. This includes the sender’s email ID, password, and the content of the email. Here’s how we can achieve this using the fetchEmailDetails function:
Future<void> fetchEmailDetails() async {
try {
// Fetch the first document from the 'settings' collection
DocumentSnapshot snapshot = await FirebaseFirestore.instance
.collection('settings')
.doc('emailDetails')
.get();
// Check if the document exists
if (snapshot.exists) {
senderEmail = snapshot['emailId'];
senderEmailPassword = snapshot['password'];
senderEmailContent = snapshot['mailContent'];
}
} catch (e) {
print('Error fetching email details: $e');
}
}
Explanation:
- Firestore Query: The function retrieves the emailDetails document from the settings collection in Firestore. This document contains the required email configuration.
- Error Handling: If there’s an issue fetching the document, the error is caught and printed to the console.
Setting Up the SMTP Server
Once we have the email configuration details, the next step is to set up the SMTP server. Here’s how to do this in our _sendEmail function:
_sendEmail() async {
String username = senderEmail;
String password = senderEmailPassword;
final smtpServer = gmail(username, password);
final message = Message()
..from = Address(username, 'Admin')
..recipients.add(currentUserEmailId)
..subject = 'Verify Your Email Address for GemFinder'
..text = 'Hello [User\'s Name],\n\nThank you for signing up for [App Name]! To complete your registration, please verify your email address by clicking the link below:\n\n[Verification Link]\n\nIf you did not request this verification, please ignore this email, and your account will remain inactive.\n\nThank you,\nThe [App Name] Team'
..html = """
<p>Hello,</p>
<p>Thank you for signing up for GemFinder! To complete your registration, please verify your email address by clicking the link below:</p>
<p><a href="https://us-central1-******.cloudfunctions.net/emaillinkLogin?userId=${currentUserId}&Time=${currentTimeStamp}">[Verification Link]</a></p>
<p>If you did not request this verification, please ignore this email, and your account will remain inactive.</p>
<p>Thank you,<br>The GemFinder Team</p>
""";
try {
final sendReport = await send(message, smtpServer);
print('Message sent: ' + sendReport.toString());
} on MailerException catch (e) {
print('Message not sent: $e');
for (var p in e.problems) {
print('Problem: ${p.code}: ${p.msg}');
}
}
}
Explanation:
- SMTP Server Configuration: We create an SMTP server instance using the Gmail function, passing in the sender’s email and password.
- Email Message Creation: We construct the email message using the Message class, specifying:
- Sender’s Address: The sender’s email and display name.
- Recipient’s Address: The recipient’s email (current user).
- Subject and Content: The subject and body of the email, both in plain text and HTML formats. The HTML content includes a verification link that the user must click to verify their email address.
Sending the Email
With the SMTP server set up and the email message created, we use the send function to send the email. If successful, a confirmation message is printed. If there’s an error (such as issues with SMTP authentication), the error details are caught and printed to the console.
Best Practices for SMTP Email Verification Login
- Environment Variables: Store sensitive information such as email credentials in environment variables or a secure configuration service to prevent hardcoding them into your application.
- Rate Limiting: Implement mechanisms to avoid sending too many emails in a short period, as this may lead to the sender’s email being flagged as spam.
- Email Verification Link: Ensure that the verification link is unique and contains parameters to identify the user securely.
Conclusion
In this second part of our blog series, we successfully set up the SMTP mailer to send verification emails using Firebase Firestore for configuration. We learned how to fetch email details, configure the SMTP server, and construct and send the email message.
In the next part, we will delve into setting up Firebase Cloud Functions to handle the verification requests when users click on the verification link in their emails. This is a critical step in completing the email verification process and ensuring that users can log in to your application securely.
Stay tuned for Part 3, where we’ll cover Firebase Cloud Functions setup in detail!