I’ve a project with the following folder structure:
enter image description here
It has a firebase cloud functions folder as well as a react app.
Here’s the code for the index.js file in the functions folder:
const functions = require("firebase-functions");
const { exec } = require("child_process");
const util = require("util");
const execPromise = util.promisify(exec);
exports.installModules = functions.https.onCall((data, context) => {
return new Promise((resolve, reject) => {
console.log("Starting install modules process");
exec(
"npm i",
{
cwd: "../react-app",
},
(err, stdout, stderr) => {
if (err) {
console.error("Error running build command:", err);
reject(err);
}
console.log("Modules installed successfully with output:", stdout);
resolve("Modules installed successfully");
}
);
});
});
exports.build = functions.https.onCall((data, context) => {
return new Promise((resolve, reject) => {
console.log("Starting build process...");
exec(
"npm run build",
{
cwd: "../react-app",
},
(err, stdout, stderr) => {
if (err) {
console.error("Error running build command:", err);
reject(err);
}
console.log("Build completed successfully with output:", stdout);
resolve("Build completed successfully");
}
);
});
});
The first function (installModules) installs modules inside the react app. The second function (build) makes a build folder for the react app. Both of these functions work fine when testing them with the firebase functions shell (with the command firebase functions:shell, and then nameOfFunction({}).
However, when running deploying these to the cloud I get the following error when calling them from a frontend.
**severity: "ERROR"
textPayload: "Unhandled error Error: spawn /bin/bash ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:285:19)
at onErrorNT (node:internal/child_process:485:16)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
errno: -2,
code: 'ENOENT',
syscall: 'spawn /bin/bash',
path: '/bin/bash',
spawnargs: [ '-c', 'npm i' ],
cmd: 'npm i'
}**
I’ve tried running these in an express server deployed to both Google Cloud and Heroku but was running into too many issues which is why I decided to give firebase cloud functions a try. According to this post it is possible to run npm commands inside of a google function.
Thanks, any help is appreciated!
2
Answers
The issue I see is you are trying to execute
/bin/bash
shell scripting throughexec
within a Firebase function. Although it may be possible, I think you’ve outgrown Firebase in this regard and may want to look into using Cloud Run which has full access toshell
without restriction and can still communicate with your GCFs (Firebase functions).Creating a Cloud Run service is really easy with the pre-made container images you can use in the Google Cloud Console GUI so you can be up and running quickly.
What you’re trying to do isn’t possible. You can’t dynamically install modules or do anything at all to modify the filesystem that was created for your function (it is a read-only docker image). From the documentation:
The question you linked does not actually say that it’s possible to run npm commands in Cloud Functions. It just says that it’s possible to spawn commands (typically that you provide in your own deployment).
If you want to run arbitrary commands to build a filesystem that you can use to execute more programs, Cloud Functions is not the right product for your use case. If you are just trying to build some software and deploy it somewhere, maybe Cloud Build is what you need as part of your deployment pipeline.