Setup Instructions
Follow these steps to deploy the Firebase Cloud Function that powers AuthMailer.
Step 1: Set up Firebase Functions
If you haven't already, initialize Firebase Functions in your project directory:
firebase init functionsChoose TypeScript when prompted. This will create a functions directory.
Step 2: Add the Function Code
Replace the content of functions/src/index.ts with the following code:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
// To send emails, you can use a service like SendGrid, Mailgun, or Nodemailer.
// Example: yarn add nodemailer
// import * as nodemailer from "nodemailer";
admin.initializeApp();
const db = admin.firestore();
// IMPORTANT: Configure your email transport.
// For production, use a dedicated email service and store credentials securely
// in Firebase Functions configuration (e.g., using functions.config()).
/*
const transporter = nodemailer.createTransport({
host: functions.config().smtp.host,
port: functions.config().smtp.port,
secure: true, // true for 465, false for other ports
auth: {
user: functions.config().smtp.user,
pass: functions.config().smtp.pass,
},
});
*/
export const onNewUserCreate = functions.auth.user().onCreate(async (user) => {
const { uid, email, displayName } = user;
const adminEmail = "admin@abhdemo.com";
if (!email) {
functions.logger.log(`User ${uid} created without an email address. No notification sent.`);
return;
}
try {
// 1. Get email configuration from Firestore (optional, could be hardcoded)
// Note: The original fields (subject, body) are now for admin notifications.
const configDoc = await db.collection("auth-mailer-config").doc("email").get();
const config = configDoc.data() || {};
const senderEmail = config.senderEmail || "noreply@yourdomain.com";
let subject = config.subject || "New User Registration: {{email}}";
let body = config.body || "A new user has registered on your platform.\n\nEmail: {{email}}\nDisplay Name: {{displayName}}\nUID: {{uid}}";
// 2. Compose email by replacing placeholders
const finalSubject = subject.replace(/{{displayName}}/g, displayName || "N/A").replace(/{{email}}/g, email).replace(/{{uid}}/g, uid);
const finalBody = body.replace(/{{displayName}}/g, displayName || "N/A").replace(/{{email}}/g, email).replace(/{{uid}}/g, uid);
// 3. Send the email to the admin address
functions.logger.info(`WOULD_SEND_EMAIL to: ${adminEmail}, subject: ${finalSubject}`);
// Example with nodemailer:
/*
await transporter.sendMail({
from: senderEmail,
to: adminEmail,
subject: finalSubject,
text: finalBody,
});
*/
// 4. Log success to Firestore for the dashboard
await db.collection("auth-mailer-logs").add({
timestamp: admin.firestore.FieldValue.serverTimestamp(),
userEmail: email,
status: "Success",
message: `Notification for new user sent to ${adminEmail}.`,
});
} catch (error) {
functions.logger.error(`Error sending new user notification to ${adminEmail}:`, error);
// 5. Log error to Firestore
await db.collection("auth-mailer-logs").add({
timestamp: admin.firestore.FieldValue.serverTimestamp(),
userEmail: email,
status: "Error",
message: error instanceof Error ? error.message : "An unknown error occurred.",
});
}
});Step 3: Install Dependencies
Navigate to the functions directory and install any necessary email-sending libraries. For example, if you choose to use Nodemailer:
cd functions && yarn add nodemailerMake sure your functions/package.json includes firebase-admin and firebase-functions.
Step 4: Configure and Deploy
Important!
You must uncomment and configure the email transport section in the code with your email provider's details. For security, use Firebase environment configuration to store sensitive keys.
Once configured, deploy your function:
firebase deploy --only functionsStep 5: Firestore Setup
The function reads configuration and writes logs to Firestore. Ensure your Firestore security rules allow the function to access these collections:
auth-mailer-config: For storing email templates. The document ID should beemail.auth-mailer-logs: For logging function activity.