3

I am using puppeteer-extra for my firebase cloud function. However, when the function was triggered, I got the error saying that puppeteer is missing and asking me to install puppeteer, while I already had had puppeteer installed. I tried installing it again but still got the same error. What goes wrong?

package.json of my functions folder

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    ......
  },
  "engines": {
    "node": "8"
  },
  "dependencies": {
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.6.1",
    "puppeteer": "^5.4.1",
    "puppeteer-extra": "^3.1.15",
    "puppeteer-extra-plugin-stealth": "^2.6.3"
  },
  "devDependencies": {
    "firebase-functions-test": "^0.2.0"
  },
  "private": true
}

the beginning of the cloud function

const functions = require('firebase-functions');
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

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

    async function XXX() {
        try {
            const browser = await puppeteer.launch({
                headless: false
            });
            ......
        }
        catch(e) {
            ......
        }
    }
}

full error message

Puppeteer is missing. :-)

    Note: puppeteer is a peer dependency of puppeteer-extra,
    which means you can install your own preferred version.

    - To get the latest stable version run: 'yarn add puppeteer' or 'npm i puppeteer'

    Alternatively:
    - To get puppeteer without the bundled Chromium browser install 'puppeteer-core'
    - To use puppeteer-firefox install 'puppeteer-firefox' and use the 'addExtra' export

update

I replaced

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

with

const puppeteer = require('puppeteer');

Then I got an error deploying the function. Error message was

Function failed on loading user code. Error message: Code in file index.js can't be loaded.
Is there a syntax error in your code?

I checked that if I switched back to puppeteer-extra without modifying any other part of the code the deployment worked fine.

Xi Liu
  • 559
  • 9
  • 18
  • I see that you've already posted your question in the correct place (https://github.com/puppeteer/puppeteer/issues/6593). Is there something more you wish to add in this thread? – MrTech Nov 11 '20 at 20:34

1 Answers1

0

I ran into a very similar issue this days and took a lot of time to realise where the error was coming from and how to fix it.

I was working on a node.js project and installed puppeteer with yarn for scraping a website, and all this setup was into a docker container (will explain later in my answer why i am mentioning this).

So the problem was exactly like yours, i was getting an error that i was missing puppeteer even though it was already installed. Tried to delete node_modules and install all over again, recreate the whole environment etc etc nothing seemed to work.

The solution that unstuck me was to add in my package.json dependencies:

"agent-base": "^6.0.2",
"https-proxy-agent": "^5.0.1",

The reason was that puppeteer was failing with that error message, which was a misleading message, but it was throwing an error from inside puppetter/node_modules/https_agent/src/agent.ts file or a similar named file i am not sure 100% about the file name.

The important thing was that the https_agent/src was not a valid path, and did not even exist but https_agent was trying to access that file and of course failed.

So by adding the agent-base base dependency fixed the issue and i was able to run my yarn command to a point where i got to the next error.

Also code wise i added some extra arguments in the launch function of Puppetter, so launch looked like:

await Puppeteer.launch({ headless: true, defaultViewport: null, args: ['--no-sandbox', '--disable-setuid-sandbox'] })

Also my imports are like the initial ones you had before updating your answer:

import Puppeteer from 'puppeteer-extra'
import Stealth from 'puppeteer-extra-plugin-stealth'

Moving from there and unstucking from my first misleading error that the whole package was missing, i had an issue into opening the headless browser upon puppeteer execution. The solution to this was in my Dockerfile to add those 2 lines:

RUN apk add git netcat-openbsd chromium
ENV PUPPETEER_EXECUTABLE_PATH="/usr/bin/chromium-browser"

After that my command ran normally, added to a crontab and everything was smooth.

Dropping here my solution and hope to help others who are stack in the same issue like i was. The biggest thing that costed most of my time was the misleading error that puppeteer is missing so i hope can i be the one to save some time from another person who is stuck in the same loop as i was.

pr1nc3
  • 8,108
  • 3
  • 23
  • 36
  • Keep in mind that each version of Puppeteer bundles a specific version of Chromium – the only version it is guaranteed to work with. https://pptr.dev/faq/#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy. When you set `PUPPETEER_EXECUTABLE_PATH` you are forcing Puppeteer to use the version of Chromium you installed with the OS package manager (apk, apt, etc...). Puppeteer might still work, but it's a risk. See also this question https://stackoverflow.com/questions/68051648/could-not-find-expected-browser-chrome-locally – jackdbd Jul 15 '22 at 15:14
  • I did not install chromium separately through my package manager. Puppeteer had it already. I did not face any issues in chromium version that's why i did not post any solution or mentioned anything in my answer and all the steps i took till i had it working. – pr1nc3 Jul 15 '22 at 20:47
  • In your Alpine-based container image you created an image layer that has some version of Chromium (see `RUN apk add git netcat-openbsd chromium`) and then the image layer with `npm install` (or `npm ci`) installed Puppeteer, which downloads a specific version of Chromium. I don't know if these 2 versions are the same one. You can also explicitly tell Puppeteer not to download Chromium by setting the environment variable `PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true` – jackdbd Jul 15 '22 at 22:10
  • I see what you mean. I did not have any issues though with chromium and puppeteer version i was using and the docker container after adding those 2 lines solved the issue that puppeteer could not launch the browser from inside the container. I guess though that if you want to install an old version of puppeteer you should adjust the chromium version too but that was not something that i faced so i did not mention it, it's good though that you brought it up. – pr1nc3 Jul 16 '22 at 15:51