Puppeteer等待页面和setTimeout在Firebase云功能中不起作用

我正在尝试加载我在Firebase上托管的页面,并使用Puppeteer将其转换为pdf。
仅使用html页面即可正常运行。
现在,我从firebase中获取数据并将其显示在页面中,因此,在创建pdf之前,我需要等待页面完全加载。
当我使用Firebase模拟器npm run serve在本地进行测试时,效果很好。
但是,它在云函数中不起作用,settimout会一直等到函数超时。
日志显示waitFor,过一会儿显示Function execution took 120002 ms,finished with status: 'timeout'
我尝试了很多我不知道该怎么办的事情,而且我开始认为这是云功能中的错误。

import * as functions from 'firebase-functions';
// tslint:disable-next-line:no-duplicate-imports
import { VALID_MEMORY_OPTIONS } from 'firebase-functions';
// import * as puppeteer from 'puppeteer';

const runtimeOpts = {
  timeoutSeconds: 120,memory: VALID_MEMORY_OPTIONS[4],};

// const cors = require('cors')({ origin: true });

export const generatePDF = functions
  .runWith(runtimeOpts)
  // .region('europe-west1')
  .https.onRequest(async (request: any,response: any) => {
    // cors(request,response,async () => {
    console.log(7);

    const hostname = request.hostname;

    let url = '';
    if (hostname === 'localhost') {
      url = 'http://localhost:5000';
    } else {
      url = 'https://myapp.firebaseapp.com';
    }

    const puppeteer = require('puppeteer');

    console.log('launch puppeteer');

    const browser = await puppeteer.launch({
      args: ['--no-sandbox','--disable-setuid-sandbox'],});
    // debug: {headless: false}

    console.log('new page');

    const page = await browser.newPage();

    console.log('goto');

    await page
      .goto(`${url}/report/A3p71Fl5GD98Sjks5BJg`)
      .catch((error: any) => {
        console.log(error);
        return response.send('Timeout1');
      });

    console.log('waitFor');

    // await page.waitFor(10000).catch((error: any) => {
    //   console.log(error);
    //   return response.send('Timeout2');
    // });

    await new Promise(resolve => setTimeout(resolve,5000));

    // await page.waitForNavigation({
    //   waitUntil: 'networkidle0',// });

    // Wait for element to render
    // await page.waitForSelector('#end');

    // await page.waitFor(10000);

    console.log('create pdf');

    const pdf = await page.pdf({
      format: 'A4',});

    console.log('close browser');

    await browser.close();

    // response.setHeader('Content-Disposition','attachment; filename=customfilename.pdf');
    response.setHeader('Content-Disposition','filename=customfilename.pdf');
    return response.type('application/pdf').send(pdf);
    // });
  });

export const helloWorld = functions.https.onRequest(
  async (request: any,response: any) => {
    await new Promise(resolve => setTimeout(resolve,5000));
    response.send('Hello from Firebase!');
  },);

// function delay(ms: number) {
//   return new Promise(resolve => setTimeout(resolve,ms));
// }

package.json:

{
  "name": "functions","scripts": {
    "lint": "tslint --project tsconfig.json","build": "tsc","serve": "npm run build && firebase serve","shell": "npm run build && firebase functions:shell","start": "npm run shell","deploy": "firebase deploy --only functions","logs": "firebase functions:log"
  },"engines": {
    "node": "8"
  },"main": "lib/index.js","dependencies": {
    "cors": "^2.8.5","firebase-admin": "^8.7.0","firebase-functions": "^3.3.0","puppeteer": "^2.0.0"
  },"devDependencies": {
    "tslint": "^5.12.0","typescript": "^3.6.3"
  },"private": true
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs","noImplicitReturns": true,"noUnusedLocals": true,"outDir": "lib","sourceMap": true,"strict": true,"target": "es2017","lib": ["dom"]
  },"compileonSave": true,"include": ["src"]
}
kakalb 回答:Puppeteer等待页面和setTimeout在Firebase云功能中不起作用

您应该将puppeteer导入功能之外,以便firebase可以重用它。另外,您无需创建超时,但可以使用await page.waitFor(5000);来代替。我试图为您的用例创建一个最小的示例。如果仍然遇到错误,请转到Firebase功能控制台并检查日志,日志应该告诉您出了什么问题。

您还可能没有在Firebase帐户上启用结算功能-在这种情况下,您的功能无法连接到第三方主机。

import * as functions from 'firebase-functions';
import * as puppeteer from 'puppeteer';

export const generatePDF = functions
    .runWith({ timeoutSeconds: 30,memory: "1GB" })
    .https.onRequest(async (request,response) => {

        const url = 'https://www.yoururl.com/';
        const browser = await puppeteer.launch({ headless: true,args: ['--no-sandbox'] });

        const page = await browser.newPage();
        await page.goto(url);
        await page.waitFor(5000);

        const pdf = await page.pdf({
            format: 'A4',});

        await browser.close();

        response.setHeader('Content-Disposition','filename=customfilename.pdf');
        return response.type('application/pdf').send(pdf);
    });
本文链接:https://www.f2er.com/3156758.html

大家都在问