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

如何在Firebase Cloud Functions中以谷歌认证用户身份发送Gmail邮件?

解决方案

方案一:通过Gmail API + OAuth2授权实现以用户邮箱发件

由于你的用户均通过谷歌账户登录,可借助Gmail API的OAuth2授权机制,让用户授予应用发送邮件的权限,从而以用户自身邮箱作为发件人发送邀请:

  1. 申请额外OAuth2权限
    在你的谷歌云项目中,为OAuth2客户端ID添加https://www.googleapis.com/auth/gmail.send权限(仅发送权限,无需读取用户邮箱)。用户登录时,引导其授权该权限。

  2. 存储刷新令牌
    用户授权成功后,会返回refresh_token(仅首次授权或用户重新授权时会返回),将此令牌加密后存储在Firebase Auth的用户自定义属性或Firestore中(务必加密,避免泄露)。

  3. 云函数中调用Gmail API发送邮件
    在Firebase Cloud Functions中,通过刷新令牌获取临时访问令牌,再调用Gmail API发送邮件。示例代码:

const { google } = require('googleapis');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

exports.sendInviteEmail = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    throw new functions.https.HttpsError('unauthenticated', '用户未登录');
  }

  // 从Firestore获取加密的refresh_token并解密
  const userDoc = await admin.firestore().collection('users').doc(context.auth.uid).get();
  const refreshToken = decrypt(userDoc.data().refreshToken); // 自行实现解密逻辑

  // 配置OAuth2客户端
  const oauth2Client = new google.auth.OAuth2(
    functions.config().google.client_id,
    functions.config().google.client_secret,
    '你的回调URL'
  );
  oauth2Client.setCredentials({ refresh_token: refreshToken });

  // 调用Gmail API发送邮件
  const gmail = google.gmail({ version: 'v1', auth: oauth2Client });
  const emailContent = [
    `From: ${data.userName} <${data.userEmail}>`,
    `To: ${data.recipientEmail}`,
    'Subject: 邀请你加入XX应用',
    '',
    `你好,${data.recipientName},${data.userName}邀请你加入XX应用,点击链接:${data.inviteLink}`
  ].join('\n');

  const encodedEmail = Buffer.from(emailContent).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');

  try {
    await gmail.users.messages.send({
      userId: 'me',
      requestBody: {
        raw: encodedEmail
      }
    });
    return { success: true };
  } catch (error) {
    throw new functions.https.HttpsError('internal', '发送邮件失败', error);
  }
});
  1. 注意事项
  • 刷新令牌需妥善加密存储,避免泄露导致用户邮箱被滥用;
  • Gmail API有发送配额,普通账户每天限制约100封,你的场景(每人每年<5封)完全满足;
  • 授权流程需在前端完成,确保用户明确知晓授权内容。

方案二:代理发件+配置SPF/DKIM(无需用户授权)

若不想让用户额外授权,可采用代理发件模式,让收件人看到的发件人是用户邮箱,实际由应用账户发送:

  1. 设置邮件头
    发送邮件时,设置From为"用户姓名 <user@example.com>",同时设置Reply-To为用户邮箱,让收件人回复时直接发给用户。示例:
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  service: 'Gmail',
  auth: {
    user: '你的应用邮箱',
    pass: '应用专用密码'
  }
});

const mailOptions = {
  from: `${userName} <${userEmail}>`, // 显示的发件人
  replyTo: userEmail, // 回复地址
  to: recipientEmail,
  subject: '邀请你加入XX应用',
  text: `你好,${recipientName},${userName}邀请你加入XX应用,点击链接:${inviteLink}`
};
  1. 配置SPF和DKIM
  • 在你的域名DNS中添加SPF记录,允许应用邮箱的服务器发送邮件;
  • 若使用Gmail作为发件服务器,需确保应用邮箱已配置DKIM,避免邮件被标记为垃圾邮件。
  1. 注意事项
  • 部分邮件服务商可能会在发件人旁标注"via 应用域名",但不影响收件人识别;
  • 此方案无需用户额外操作,体验更流畅,适合你的事务性邀请场景。

内容的提问来源于stack exchange,提问作者Peter Varga Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:12:54