【问题标题】:Unable to call Firebase Cloud Function from client-side with fetch无法通过 fetch 从客户端调用 Firebase Cloud Function
【发布时间】:2021-11-27 20:22:33
【问题描述】:

我有几个遵循此语法的 Firebase 云函数:

exports.sendText = functions.https.onCall((data, context) => {...

这总是很好用,但我一直在为我最近部署的这个新的“发布”功能而苦苦挣扎。这就是它的定义...

payment_app.post("/create-payment-intent", async (req, res) => {
    const { items } = req.body;

    // Create a PaymentIntent with the order amount and currency
    const paymentIntent = await stripe.paymentIntents.create({
        amount: calculateOrderAmount(items),
        currency: "usd",
        automatic_payment_methods: {
            enabled: true,
        },
    });

    res.send({
        clientSecret: paymentIntent.client_secret,
    });
});
exports.payment = functions.https.onRequest(payment_app)

这就是我从客户端调用它的方式。

function buyProduct(id, quantity) {
    fetch('payment_app/create-payment-intent', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            items: [
                { id: id, quantity: quantity }
            ]
        })
    }).then(res => {
        if (res.ok) return res.json()
        return res.json().then(json => Promise.reject(json))
    }).then(({ url }) => {
        console.log(url)
        Object.assign(document.createElement('a'), { target: '_blank', href: url }).click();
        var refreshVerify = setInterval(() => {
            let payment_status = localStorage.getItem("payment_status")
            if (payment_status) {
                clearInterval(refreshVerify)
                localStorage.removeItem("payment_status")
                if (payment_status === "success") {
                    console.log("payment success")
                } else if (payment_status === "cancel") {
                    console.log("payment cancel")
                } else {
                    console.log("error local_payment_status variable not valid")
                }
            }
        }, 1000)
    }).catch(e => {
        console.error(e.error)
    })
}

这样做会返回 404 not found 错误:

script.js:3849 POST http://localhost:1234/payment_app/create-payment-intent 404 (Not Found)
buyProduct @ script.js:3849
testFunction @ script.js:3845
(anonymous) @ script.js:1257
setTimeout (async)
showApp @ script.js:1242
parcelRequire.script.js.firebase/compat/app @ script.js:1209
newRequire @ script.75da7f30.js:47
(anonymous) @ script.75da7f30.js:81
(anonymous) @ script.75da7f30.js:120
script.js:3880 undefined

谁能帮我弄清楚我做错了什么?如果重要的话,这是我的 firebase.json。我想我这里可能有问题?

{
  "functions": {
    "engines": {
      "node": "14"
    },
    "source": "functions"
  },
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "payment_app/**",
        "function": "create-payment-intent",
        "destination": "/index.html"
      }
    ]
  }
}

【问题讨论】:

    标签: javascript firebase google-cloud-functions


    【解决方案1】:

    在您的 Cloud Functions 代码中,您正在实现一个可调用函数。来自关于可调用函数的文档:

    请务必记住,HTTPS 可调用函数与 HTTP 函数相似但不完全相同。要使用 HTTPS 可调用函数,您必须使用适用于您平台的客户端 SDK 以及 functions.https 后端 API(或实现协议)。

    所以你不能简单地fetch() 来调用这个函数,因为它没有实现正确的协议。相反,您应该按照calling a function from your client-side application code 上的文档中所示调用它。

    如果您在不存在可调用 SDK 的客户端平台上:

    如果您想为基于不受支持的平台构建的应用添加类似功能,请参阅Protocol Specification for https.onCall

    【讨论】:

    • 感谢弗兰克,我仍然无法弄清楚,但感谢您为我指明了正确的方向。 Stripe 元素的示例文档显示了我描述的语法,但我无法弄清楚如何将其转换为您提到的函数类型。我也尝试过在 Freelancer 上招聘人员,但我也找不到能解决这个问题的人。感谢您帮助我弄清楚我做错了什么,我已经坚持了一周了。也许如果我向更有经验的人展示这篇文章,他们将能够修复它。
    • “我还是想不通” 您对我提供的文档链接中的信息做了什么尝试?您需要使用 SDK 进行调用,或者自己实现正确的协议。
    • 您发送的链接显示了我已经熟悉的使用 onCall((data, context) 的语法...但在 Stripe 元素文档中:stripe.com/docs/payments/quickstart 它表明我需要做 res .send,但没有 res 变量。如果我执行 context.send,或者如果我重命名变量 req/res 而不是 data/context,它没有任何区别,我也不希望它有任何区别。我的每个资源可以找到了解它使用 Angular/React/Vue/另一个框架。我在一个已完成 99% 的项目上使用 vanilla JavaScript,并且不想使用另一个框架。
    • 但是我找不到任何指南或教程来说明如何执行此操作,并且 Stripe 文档显示的语法与您所说的用于调用该函数的语法完全不同,我已经看到我能找到的每个 YouTube 视频,包括尝试理解使用我不熟悉的框架的视频。所以我不确定目前我可以采取哪些步骤来解决这个问题。
    • 您所指的 Stripe 文档更有可能使用的是常规 HTTP 函数,而不是 Firebase 的自定义 Callables。此处记录了常规 HTTP 函数:firebase.google.com/docs/functions/http-events
    猜你喜欢
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    相关资源
    最近更新 更多