You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS/Swift:如何用Firebase验证用户邮箱但不用于认证?

解决方案:自定义邮箱验证流程(不影响手机号登录)

完全可以实现需求,不需要修改Firebase Auth的用户登录方式,全程基于Firestore和云函数自定义验证流程,步骤如下:

1. 完善Firestore用户数据结构

确保你的users集合下的用户文档包含以下字段:

  • phoneNumber: 已认证的手机号(来自Firebase Auth)
  • marketingEmail: 用户添加的营销邮箱
  • emailVerified: 布尔值,初始为false

2. 编写云函数触发验证邮件发送

创建一个Firestore触发器云函数,当用户文档的marketingEmail字段被新增或更新时,自动生成验证令牌并发送邮件:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const jwt = require("jsonwebtoken"); // 需要提前安装jsonwebtoken包

admin.initializeApp();

// 生成带过期时间的验证令牌
function generateVerificationToken(userId, email) {
  return jwt.sign(
    { userId, email },
    functions.config().jwt.secret, // 在Firebase控制台配置JWT密钥
    { expiresIn: "7d" } // 设置令牌7天内有效
  );
}

// 发送验证邮件
async function sendVerificationEmail(email, token) {
  const verificationUrl = `https://your-project-id.cloudfunctions.net/verifyEmail?token=${token}`;
  const mailOptions = {
    from: "你的应用 <noreply@your-app.com>",
    to: email,
    subject: "验证你的营销邮箱",
    html: `<p>点击以下链接完成邮箱验证:</p><a href="${verificationUrl}">验证邮箱</a>`
  };
  // 这里假设使用Firebase官方的「Trigger Email」扩展,写入mail集合即可触发发送
  await admin.firestore().collection("mail").add(mailOptions);
}

// Firestore触发器:监测营销邮箱字段变更
exports.onMarketingEmailUpdated = functions.firestore
  .document("users/{userId}")
  .onUpdate(async (change, context) => {
    const beforeData = change.before.data();
    const afterData = change.after.data();
    // 仅当营销邮箱新增或变更时执行逻辑
    if (beforeData?.marketingEmail !== afterData?.marketingEmail && afterData.marketingEmail) {
      const token = generateVerificationToken(context.params.userId, afterData.marketingEmail);
      await sendVerificationEmail(afterData.marketingEmail, token);
    }
    return null;
  });

3. 编写验证邮箱的HTTP云函数

创建一个HTTP云函数,处理用户点击验证链接后的请求,更新Firestore的emailVerified状态:

exports.verifyEmail = functions.https.onRequest(async (req, res) => {
  const token = req.query.token;
  if (!token) {
    return res.status(400).send("缺少验证令牌");
  }
  try {
    const decoded = jwt.verify(token, functions.config().jwt.secret);
    const userId = decoded.userId;
    const email = decoded.email;
    
    // 校验用户文档中的邮箱是否与令牌一致
    const userDoc = await admin.firestore().collection("users").doc(userId).get();
    if (!userDoc.exists || userDoc.data().marketingEmail !== email) {
      return res.status(400).send("无效的验证请求");
    }
    
    // 更新邮箱验证状态
    await userDoc.ref.update({ emailVerified: true });
    res.send("邮箱验证成功!");
    // 也可以改为跳转至App Deeplink,引导用户返回应用
  } catch (error) {
    res.status(400).send("验证令牌无效或已过期");
  }
});

关键注意事项

  • 全程无需修改Firebase Auth的用户记录,用户登录方式始终保持手机号认证,与营销邮箱验证流程完全独立。
  • JWT密钥需要在本地执行firebase functions:config:set jwt.secret="你的自定义密钥"完成配置,再部署云函数。
  • 邮件发送也可集成SendGrid、Mailgun等第三方服务,替代Firebase的「Trigger Email」扩展,实现更灵活的邮件定制。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:20:39