使用云功能在firebase中创建文档时发送电子邮件

问题描述 投票:0回答:1

我目前正在构建一个 flutter 应用程序,允许用户请求与其他人会面。当一个用户请求另一用户时,被请求的用户应该收到一封电子邮件,说明他们收到了请求。创建新请求时,一个新文档会附加到集合中

meeting_requests.
使用 Google Cloud 功能,我能够使用 Nodemailer 编写以下代码,以便在创建请求时发送电子邮件:

const transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: <MY EMAIL HERE>
    pass: <MY APPS PASSWORD HERE>,
  },
});

exports.sendMeetingNotification = functions.firestore
    .document("meeting_requests/{docId}")
    .onCreate(async (snap, context) => {
      const data = snap.data();
      const receiverId = data.receiverId;

      console.log("Fetching user data for receiverId:", receiverId);

      try {
        const userDoc = await admin.firestore().collection(
            "users").doc(receiverId).get();

        if (!userDoc.exists) {
          console.log("No user found with the given receiverId:", receiverId);
          return;
        }

        const email = userDoc.data().email;

        console.log("Found user with email:", email);

        const mailOptions = {
          from: "\"ConnectEd\" [email protected]",
          to: email,
          subject: "New Meeting Request from Teacher",
          html: `
        <div style="background-color: #f9f7cf; padding: 20px;
         font-family: Arial, sans-serif; color: #333;">
          <div style="text-align: center; margin-bottom: 20px;">
            <img src="https://your-logo-url.com/logo.png" alt="ConnectEd Logo" style="width: 100px; height: auto;" />
          </div>
          <div style="background-color: #fff; 
          padding: 20px; border-radius: 8px; 
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);">
            <h2 style="color: #2c3e50;
            ">New Meeting Request from ${data.senderName}</h2>
            <p style="font-size: 16px; line-height: 1.6;">
              <strong>Note from teacher:</strong> ${data.note}
            </p>
            <p style="font-size: 16px; line-height: 1.6;">
              Please click the link below to view the request:
            </p>
            <div style="text-align: center; margin: 20px 0;">
              <a href="yourapp://app/openRequest?requestId=${context.params.docId}" style="background-color: #f39c12; color: #fff; padding: 10px 20px; text-decoration: none; border-radius: 5px; font-size: 16px;">View Request</a>
            </div>
          </div>
          <div style="text-align: center; 
          margin-top: 20px; font-size: 12px; color: #999;">
            <p>© 2024 ConnectEd. All rights reserved.</p>
            <p>If you did not request this email, please ignore it.</p>
          </div>
        </div>
        `,
        };

        console.log("Sending email to:", email);

        await transporter.sendMail(mailOptions);
        console.log("Email sent successfully to:", email);
      } catch (error) {
        console.error("Error sending email notification:", error);
      }
    });


但是,当我运行它时,没有发送电子邮件,并且出现以下日志错误:

2024-09-07T14:37:34.038106Z ? sendMeetingNotification: Error sending email notification: Error: 7 PERMISSION_DENIED: Missing or insufficient permissions.
2024-09-07T14:37:34.038127Z ? sendMeetingNotification:     at callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:31:19)

2024-09-07T14:37:34.038251Z ? sendMeetingNotification:   code: 7,
2024-09-07T14:37:34.038256Z ? sendMeetingNotification:   details: 'Missing or insufficient permissions.',
s.',
2024-09-07T14:37:34.038261Z ? sendMeetingNotification:   metadata: Metadata {
2024-09-07T14:37:34.038266Z ? sendMeetingNotification:     internalRepr: Map(1) { 'x-debug-tracking-id' => [Array] },
d' => [Array] },
2024-09-07T14:37:34.038270Z ? sendMeetingNotification:     options: {}
2024-09-07T14:37:34.038274Z ? sendMeetingNotification:   }
2024-09-07T14:37:34.038274Z ? sendMeetingNotification:   }
2024-09-07T14:37:34.038279Z ? sendMeetingNotification: }
2024-09-07T14:37:34.039269068Z D sendMeetingNotification: Function execution took 54 ms, finished with status: 'ok'

我是新手,所以真的不明白发生了什么。

我尝试更改 Firebase 权限,将此 Gmail 帐户添加到我的云权限中,但没有任何效果。奇怪的是,昨天它工作得很好,今天却不行了,这让我很困惑。

感谢您的帮助!

javascript flutter firebase google-cloud-platform nodemailer
1个回答
0
投票

在发送电子邮件之前将 firestore 逻辑包装到 try/catch 中,因为这不是 nodemailer 的错误。该错误意味着用于您的 gcp 函数的服务帐户没有权限从 firestore 查询数据。

在 gcp console iam 服务中检查服务帐户的权限。

© www.soinside.com 2019 - 2024. All rights reserved.