Firebase Function报错:无法找到function app的有效端点
解决:Error: Unable to find a valid endpoint for function app
问题场景
本地模拟器中Firebase Functions可正常运行,但部署后前端调用后端服务时触发错误:Error: Unable to find a valid endpoint for function app。
原始配置文件(firebase.json)
"hosting": { "public": "build", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [ { "source": "**", "destination": "/index.html" }, { "source": "/bigben", "function": "bigben", "region": "us-central1" }, { "source": "/create-customer-portal-session", "function": "app" } ] }
原始Functions代码(index.js)
const functions = require('firebase-functions'); const express = require('express'); const app = express(); const cors = require('cors')({origin: true}); app.use(cors); exports.app = functions.https.onRequest(app); exports.bigben = functions.https.onRequest((req, res) => { const hours = (new Date().getHours() % 12) + 1 // London is UTC + 1hr; res.status(200).send(`<!doctype html> <head> <title>Time</title> </head> <body> ${'BONG '.repeat(hours)} </body> </html>`); }); const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY) const priceId = 'price_1LaJC1CKMdmWgnyspBbFet9v'; const storeItems = new Map([ [ 1, { priceInCents: 10000, name: 'Item 1 Name'} ], [ 2, { priceInCents: 20000, name: 'Item 2 Name'} ], ]) app.post("/create-checkout-session", async (req, res) => { const cust = req.body.customerId const price = req.body.priceId const quantity = req.body.students const quantityA = Number(quantity) try { const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], mode: 'subscription', allow_promotion_codes: true, customer: cust, line_items: [ { price: price, // For metered billing, do not pass quantity quantity: quantityA, }, ], success_url: `https://learning-platform.web.app/`, cancel_url: `https://learning-platform.web.app/`, }) res.redirect(session.url); } catch (e) { res.status(500).json({ error: e.message }) } }) app.post('/create-customer-portal-session', async (req, res) => { const cust = req.body.customerId // Authenticate your user. const session = await stripe.billingPortal.sessions.create({ customer: cust, }); console.log(session.url) res.redirect(session.url); });
部署日志截图


问题根源与修复方案
1. Rewrite规则顺序错误(直接导致找不到端点)
Firebase Hosting的rewrite规则按顺序匹配,第一个通配符规则"source": "**"会拦截所有请求,导致后续指向app函数的规则从未被触发。
修复:将通配符规则移到rewrites数组末尾,并为app函数显式指定与部署日志一致的region(此处为us-central1):
"hosting": { "public": "build", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [ { "source": "/bigben", "function": "bigben", "region": "us-central1" }, { "source": "/create-customer-portal-session", "function": "app", "region": "us-central1" }, { "source": "**", "destination": "/index.html" } ] }
2. Express未配置请求体解析
当前代码未添加请求体解析中间件,导致POST请求中的req.body为undefined,会引发Stripe相关参数错误。
修复:在Express初始化后添加解析中间件:
const express = require('express'); const app = express(); const cors = require('cors')({origin: true}); // 添加请求体解析 app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cors);
3. Stripe Portal Session缺少必填参数
Stripe的billingPortal.sessions.create方法必须指定return_url,否则会抛出错误。
修复:补充return_url参数:
app.post('/create-customer-portal-session', async (req, res) => { const cust = req.body.customerId const session = await stripe.billingPortal.sessions.create({ customer: cust, return_url: "https://learning-platform.web.app/" // 添加返回URL }); console.log(session.url) res.redirect(session.url); });
4. 重新部署
执行部署命令:
firebase deploy --only functions,hosting
验证
部署完成后,前端调用/create-customer-portal-session路径即可正常触发app函数,不会再出现找不到端点的错误。
内容的提问来源于stack exchange,提问作者Peter Bonnebaigt
相关产品推荐
相关产品推荐

