【问题标题】:How to use koa.js + next in Firebase Functions如何在 Firebase Functions 中使用 koa.js + next
【发布时间】:2025-11-24 16:25:01
【问题描述】:

我想使用 Cloud Functions for Firebase 为 shopify 应用部署 React 应用。

我是 Next 和 Koa 的新手。

基于repo,下面的代码是如何在 Firebase 中托管一个简单的 React 应用程序。

const path = require('path')
const functions = require('firebase-functions')
const next = require('next')

var dev = process.env.NODE_ENV !== 'production'
var app = next({
  dev,
  conf: { distDir: `${path.relative(process.cwd(), __dirname)}/next` }
})
var handle = app.getRequestHandler()

exports.next = functions.https.onRequest((req, res) => {
  console.log('File: ' + req.originalUrl) // log the page.js file that is being requested
  return app.prepare().then(() => handle(req, res))
})

哪个工作正常,没问题。

然后基于this tutorial from shopify 我需要在server.js 中集成koa 和其他依赖项,在我的情况下我认为它应该放在firebase 函数中。所以我得到了这段代码

const path = require('path')
const isomorphicFetch = require('isomorphic-fetch');
const Koa = require('koa');
const functions = require('firebase-functions')
const next = require('next');
const ShopifyConfig = require('./shopify.js');

const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
const dotenv = require('dotenv');
const { verifyRequest } = require('@shopify/koa-shopify-auth');
const session = require('koa-session');

dotenv.config();

const port = parseInt(process.env.PORT, 10) || 3000;

var dev = process.env.NODE_ENV !== 'production'
var app = next({
  dev,
  conf: { distDir: `${path.relative(process.cwd(), __dirname)}/next` }
})
var handle = app.getRequestHandler()

const server = new Koa();

server.use(session(server));
server.keys = [ShopifyConfig.secretKey];

server.use(
  createShopifyAuth({
    apiKey: ShopifyConfig.key,
    secret: ShopifyConfig.secretKey,
    scopes: [],
    afterAuth(ctx) {
      const { shop, accessToken } = ctx.session;
      ctx.redirect('/');
    },
  }),
);

server.use(verifyRequest());

server.use(async (ctx) => {
  await handle(ctx.req, ctx.res);
  ctx.respond = false;
  ctx.res.statusCode = 200;

});

exports.next = functions.https.onRequest((req, res) => {
  console.log('File: ' + req.originalUrl) // 

  // This is old code
  // return app.prepare().then(() => {
  //   handle(req, res);
  // })

  // I tried this #1
  // server.callback(req, res);
})

// I tried this #2
// exports.next = functions.https.onRequest(server.callback);

// I tried this #3
// exports.next = functions.https.onRequest(server.callback());

// I tried this #4
exports.next = functions.https.onRequest((req, res) => {
  console.log('File: ' + req.originalUrl) 

  return app.prepare().then(() => {
    server.callback(req, res);
    //handle(req, res);
  })
})

我的问题现在基于 Koa,functions.https.onRequest 中应该包含什么代码?请注意,没有用于监听端口的代码,因为它对 firebase 函数没有意义。

我试过#1、#2、#3,还有this post

1 -> 我得到请求超时

2 -> 我得到请求超时

3 -> 我得到“无法访问未定义的中间件”

4 -> 我得到请求超时

【问题讨论】:

  • 确保你返回一个承诺(这是关键),你会因此而超时,其他一切似乎都是正确的,我假设你想管理你的路线到 koa 并委派一个点进入下一个功能,对吧?
  • @andresmijares 我是 koa 和 next 的新手,这些是 shopify 文档中的说明,所以我认为您的问题的答案是肯定的。在最终服务器侦听端口 3000 的文档中,firebase 函数中应该包含什么,而不是我尝试使用 server.call back 这是无效的,然后我尝试返回一个新的 Promise 并在回调后解析并且仍然相同
  • 这是 cors 问题...如果你能详细说明一下,将 cors 添加到你的函数中,它会更容易帮助你:)
  • @andresmijares 当它像 exports.next = functions.https.onRequest((req, res) => { console.log('File: ' + req.originalUrl) // log the page.js file that is being requested return app.prepare().then(() => handle(req, res)) }) 工作正常时,我认为它与 cors 无关

标签: node.js firebase google-cloud-functions next koa


【解决方案1】:
const functions = require('firebase-functions');
const app = new Koa();

...

exports['http'] = functions.https.onRequest(app.callback());

【讨论】:

  • 所提供的答案被标记为低质量帖子以供审核。以下是How do I write a good answer? 的一些指南。提供的这个答案可能是正确的,但它可以从解释中受益。仅代码答案不被视为“好”答案。来自review
【解决方案2】:

感谢kvindasAB

server.callback 本身不是回调,而是一个根据我假设的配置生成回调的函数。

所以代码需要改成

server.callback()(req, res);

【讨论】: