You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Functions中Async/Await使用异常:部署后返回空响应

Firebase Functions部署后Puppeteer接口返回空响应,本地调试正常

问题描述

在Firebase Functions中使用Async/Await结合Puppeteer编写网页抓取接口,本地通过firebase serve测试可正常返回渲染后的HTML,但部署到线上后接口仅返回空响应{}。此外,预部署时ESLint触发Parsing error: Unexpected token function错误,移除firebase.json中的predeploy lint配置后部署成功,但线上接口异常。

代码示例

const functions = require("firebase-functions");
const puppeteer = require('puppeteer');

async function getHtml(url) {
    const browser = await puppeteer.launch({
        headless: true,
        args: ['--no-sandbox', '--disable-setuid-sandbox',]
    });

    const page = await browser.newPage();

    await page.goto(url,
        { waitUntil: ['networkidle0', 'networkidle2', 'load', 'domcontentloaded'] });
    const k = await page.content()

    await browser.close();
    return k
};

exports.api = functions.runWith({ memory: '512MB' })
    .https.onRequest((request, response) => {
        functions.logger.info("Hello logs!", { structuredData: true });
        getHtml(request.query.url)
            .then(function (res) {
                response.send(res);
                console.log(res)
            })
            .catch(function (err) {
                response.send(err);
            })
    });

复现步骤

  • 执行firebase init,选择Functions、JavaScript(可关闭ESLint);
  • 安装puppeteer:npm install puppeteer;
  • 将上述代码粘贴到/functions/index.js;
  • 本地执行firebase serve,测试带url参数的接口,可正常返回渲染后的HTML;
  • 执行firebase deploy后,访问线上接口并添加url参数,仅返回{}。

解决方案

1. 修复ESLint语法错误(可选,推荐保留lint)

若需保留预部署的ESLint检查,修改functions/.eslintrc.js中的parserOptions.ecmaVersion为2017或更高版本,以支持async/await语法:

module.exports = {
  root: true,
  env: {
    es6: true,
    node: true,
  },
  parserOptions: {
    ecmaVersion: 2017, // 或更高版本如2020
  },
  rules: {
    // 保留原有规则或按需调整
  },
};

2. 适配Puppeteer在Firebase云环境运行

Firebase Functions的Linux环境与本地存在差异,默认puppeteer包可能无法正常运行,改用puppeteer-core配合chrome-aws-lambda:

  • 卸载原puppeteer:
npm uninstall puppeteer
  • 安装适配包:
npm install puppeteer-core chrome-aws-lambda
  • 修改getHtml函数代码:
const chromium = require('chrome-aws-lambda');
const puppeteer = require('puppeteer-core');

async function getHtml(url) {
    const browser = await puppeteer.launch({
        args: chromium.args,
        defaultViewport: chromium.defaultViewport,
        executablePath: await chromium.executablePath,
        headless: chromium.headless,
    });

    const page = await browser.newPage();

    // 简化waitUntil参数,避免不必要的等待超时
    await page.goto(url, { waitUntil: ['networkidle2', 'domcontentloaded'] });
    const html = await page.content();

    await browser.close();
    return html;
};

3. 调整函数资源配置

Puppeteer运行Chrome需要足够内存和超时时间,修改函数配置:

exports.api = functions.runWith({ 
    memory: '1GB', // 至少1GB,可按需调整至2GB
    timeoutSeconds: 90 // 延长超时时间,最大支持540秒
})
.https.onRequest(async (request, response) => {
    functions.logger.info("Request received", { url: request.query.url });
    try {
        const url = request.query.url;
        // 校验参数是否存在
        if (!url) {
            response.status(400).send("Missing 'url' query parameter");
            return;
        }
        const html = await getHtml(url);
        response.send(html);
        functions.logger.info("HTML fetched successfully");
    } catch (err) {
        // 记录详细错误日志到Firebase控制台
        functions.logger.error("Fetch failed", { error: err.message, url: request.query.url });
        response.status(500).send(`Error: ${err.message}`);
    }
});

4. 指定Node.js版本

在functions/package.json中明确指定与本地一致的Node.js版本(Firebase支持14/16/18/20版本):

{
  "engines": {
    "node": "18"
  }
}

5. 排查线上日志

登录Firebase控制台,进入Functions的日志页面,查看具体错误信息(如Chrome启动失败、页面加载超时、参数异常等),辅助定位问题。

内容的提问来源于stack exchange,提问作者Vayun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 19:20:47