如何将COR添加到Firebase OnCall功能

发布于 2025-02-12 17:46:23 字数 2053 浏览 0 评论 0 原文

我正在尝试使用 onCall 函数发送电子邮件。该功能是由网站中的表单提交触发的。这是我的代码

const nodemailer = require('nodemailer');
const cors = require('cors')({
  origin: true
});
admin.initializeApp(functions.config().firebase);

let transporter = nodemailer.createTransport({
  host: 'xxx',
  port: xxx,
  secure: true, // use SSL
  auth: {
    user: 'xxx',
    pass: 'xxx' 
  }
});


exports.sendEmail = functions.https.onCall((req, res) => {
  cors(req, res, () => {
    const email = req.email;
    const name = req.name;
    const message = req.message;
    const subject = req.subject
    const sender = `xxx`;
    const recipient = `xxx`;
    const mailOptions = {
      from: sender,
      to: recipient,
      subject: `New web enquiry!`,
      html: `<h1>Notification from ${subject}</h1>
              <p>
                <b>Name: </b>${name}<br>
                <b>Email: </b>${email}<br>
                <b>Message: </b>${message}<br>
              </p>`
    };
    return transporter.sendMail(mailOptions, (error, data) => {
      if (error) {
        console.log(error)
        return res.status(403).send(error.toString());
      }
      console.log("Email Sent!")
      return res.status(200).send('Sent');
    });
  });
});

,当函数触发时,我

> Unhandled error TypeError: Cannot read property 'origin' of undefined
>     at /workspace/node_modules/cors/lib/index.js:219:40
>     at optionsCallback (/workspace/node_modules/cors/lib/index.js:199:9)
>     at corsMiddleware (/workspace/node_modules/cors/lib/index.js:204:7)
>     at /workspace/index.js:880:3
>     at fixedLen (/workspace/node_modules/firebase-functions/lib/providers/https.js:120:41)
>     at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:400:32
>     at processTicksAndRejections (internal/process/task_queues.js:95:5)

有趣地收到了此错误,带有 onRequest 函数的相同代码可以正常工作。

谁能向此发光?

谢谢

I am trying to send email with Firebase using an onCall function. The function is triggered by a form submission in a website. This is my code

const nodemailer = require('nodemailer');
const cors = require('cors')({
  origin: true
});
admin.initializeApp(functions.config().firebase);

let transporter = nodemailer.createTransport({
  host: 'xxx',
  port: xxx,
  secure: true, // use SSL
  auth: {
    user: 'xxx',
    pass: 'xxx' 
  }
});


exports.sendEmail = functions.https.onCall((req, res) => {
  cors(req, res, () => {
    const email = req.email;
    const name = req.name;
    const message = req.message;
    const subject = req.subject
    const sender = `xxx`;
    const recipient = `xxx`;
    const mailOptions = {
      from: sender,
      to: recipient,
      subject: `New web enquiry!`,
      html: `<h1>Notification from ${subject}</h1>
              <p>
                <b>Name: </b>${name}<br>
                <b>Email: </b>${email}<br>
                <b>Message: </b>${message}<br>
              </p>`
    };
    return transporter.sendMail(mailOptions, (error, data) => {
      if (error) {
        console.log(error)
        return res.status(403).send(error.toString());
      }
      console.log("Email Sent!")
      return res.status(200).send('Sent');
    });
  });
});

When the function triggers, I get this error

> Unhandled error TypeError: Cannot read property 'origin' of undefined
>     at /workspace/node_modules/cors/lib/index.js:219:40
>     at optionsCallback (/workspace/node_modules/cors/lib/index.js:199:9)
>     at corsMiddleware (/workspace/node_modules/cors/lib/index.js:204:7)
>     at /workspace/index.js:880:3
>     at fixedLen (/workspace/node_modules/firebase-functions/lib/providers/https.js:120:41)
>     at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:400:32
>     at processTicksAndRejections (internal/process/task_queues.js:95:5)

Interestingly, the same code with an onRequest function works ok.

Can anyone shine some light into this?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只想待在家 2025-02-19 17:46:25

对于到达这里搜索firebase callable功能的任何其他人,请记录清单:

  • 确保正确部署该功能。
  • 确保功能名称正确。
  • 确保功能代码本身不会引发错误。 使用
    模拟器以帮助
  • 确保您的区域匹配

注意:所有这些都会导致CORS错误,如果您可以在功能日志中找到错误而不是在幻觉中找到错误,那就更好了。

现在,完成此清单后,让我们解决问题“具有OnRequest函数的相同代码可以正常工作。那么,为什么不使用OnCall呢?”

Firebase具有创建HTTP云功能的两种不同方法,一个是 onRequest 方法,另一种是使用 onCall 方法。
这两个功能都会创建一个可以调用的HTTP端点。最大的区别在于您如何称呼它们。
OnRequest函数遵循更常规的nodejs api(Kinda Like Express),您可以在其中调用端点,在内部,您可以获得请求和响应,并且像大多数Node JS应用程序一样使用该请求和响应。

export const helloWorld = functions.https.onRequest((request, response) => {
  response.send("I'm a Firebase HTTP Function");
});

ONCALL功能是一个特殊的包装器,最重要的是,它利用UI和服务器端的Firebase JavaScript SDK,它将为您处理大多数复杂零件,例如自动从用户身份验证的状态中从客户无需做额外的工作。它将数据和上下文作为参数传递。

export const sayHello = functions.https.onCall((data, context) => {
  // data holds the 'body' being sent
  // context holds metadata like headers, authentication, etc.
  return { message: 'I am a callable function' };
});
 

作为一般指南,它们均运行良好,在执行服务器对服务器通信时使用OnRequest函数,例如试图将另一个后端系统连接到云功能时。并在调用UI调用云功能时使用OnCall函数,这样,Firebase JS SDK可以处理身份验证。

因此,如果从应用程序 /网站(例如表单提交网站)中调用https可呼叫函数,则必须调用对您的可可函数的引用( firebase.functions()。 ')在您的HTML页面中,包括firebaseconfig,处理客户端错误,如 example 。您也可以关注此文档

  1. href 在服务器端部署功能。
    两个参数数据,上下文和返回数据作为JSON
    编码。

  2. 处理错误以确保客户端获得有用的错误详细信息,
    通过投掷或返回承诺来返回可呼叫的错误
    被拒绝)functions.https.httpserror的实例。错误
    具有代码属性,可以是列出的值之一
    functions.https.httpserror。错误还具有字符串消息,
    默认为空字符串。如果httpserror以外的错误
    是从您的功能中抛出的,您的客户会收到错误
    带有内部和代码内部的消息。

  3. 保存完整的可呼叫后,部署可呼叫功能
    index.js中的功能,运行

    firebase部署 - 只是
    功能:AddMessage

  4. 现在在客户端,设置环境,无论您想什么
    做,手动需要燃烧核心和云功能,包括
    来自firebase控制台的Firebaseconfig

  5. 最终通过调用参考来调用客户端的功能
    httpsCallable(functions,'functionName');

如果未从客户端应用程序/网站调用HTTPS可呼叫功能,则必须使用POST方法调用内容,则内容类型必须为application/json或application/json; charset = utf-8,并且身体必须包含一个名为数据的字段,以使数据传递给该方法。所有这些都已记录在此处。本节为客户端SDK使用的HTTPS请求和响应格式提供了规范,以实现API。

For anybody else who has arrived here searching firebase callable functions cors errors, here's my checklist:

  • Ensure the function is deployed correctly.
  • Ensure the function name is correct.
  • Ensure the function code itself is not throwing an error. Use the
    emulator to help
  • Ensure your regions match

Note : All these can lead to cors errors, it's better if you can find the error in functions logs rather than having in the illusion it's a CORS error.

Now after this checklist is done, let's get to the question “the same code with an onRequest function works ok. So why not with onCall?”.

Firebase has two different ways for creating HTTP Cloud Functions, one is the onRequest method, and the other one is using the onCall method.
Both of these functions create an HTTP endpoint that you can call. The big difference is in how you call them.
The onRequest functions follow the more regular nodejs API (Kinda like express) where you call the endpoint, and inside, you get the request and response, and you work with that like most node js applications.

export const helloWorld = functions.https.onRequest((request, response) => {
  response.send("I'm a Firebase HTTP Function");
});

The onCall function is a special wrapper on top of that, that takes advantage of the Firebase JavaScript SDK from both UI and server-side, which will handle most of the complex parts for you, like automatically passing the state of the user’s authentication from the client without you having to do extra work. It passes data and context as parameters.

export const sayHello = functions.https.onCall((data, context) => {
  // data holds the 'body' being sent
  // context holds metadata like headers, authentication, etc.
  return { message: 'I am a callable function' };
});
 

They both work well, as a general guideline, use the onRequest functions when doing server-to-server communication, like when trying to connect another backend system to cloud functions. And use the onCall functions when calling Cloud Functions from the UI, that way, the Firebase JS SDK can handle authentication.

So if HTTPS Callable functions are called from App / website like form submission website in your case, you have to call the reference to your callable function (firebase.functions().httpsCallable(‘your-function-name’) there in your html page, include the firebaseConfig, handle the client error like shown in this example. You can also follow this documentation which outlines how to call callable functions from App.

  1. Write and deploy the function on the server-side. Look how they take
    two parameters data, context and return data to client as JSON
    encoded.

  2. Handle errors To ensure the client gets useful error details,
    return errors from a callable by throwing (or returning a Promise
    rejected with) an instance of functions.https.HttpsError. The error
    has a code attribute that can be one of the values listed at
    functions.https.HttpsError. The errors also have a string message,
    which defaults to an empty string. If an error other than HttpsError
    is thrown from your functions, your client instead receives an error
    with the message INTERNAL and the code internal.

  3. Deploy the callable function After you save a completed callable
    function within index.js, run

    firebase deploy --only
    functions:addMessage

  4. Now in the client side, set up the environment whatever you want to
    do, manually require both Firebase core and Cloud Functions, include
    the FirebaseConfig from the Firebase console.

  5. Finally call the function in the client, by calling the reference
    httpsCallable(functions,’functionName’);

If HTTPS Callable functions are not called from client App/ website it must be called using the POST method, the Content-Type must be application/json or application/json; charset=utf-8, and the body must contain a field called data for the data to be passed to the method. All of this has been documented here. This section provides a specification for the HTTPS request and response formats used by the client SDKs to implement the API.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文