I'm able to deploy my Next.js project to Firebase Functions successfully as per this post. However, when I try to visit my project in the browser, I get a Error: could not handle the request error, and in the Functions log I see this error message:
Error: Could not find a production build in the '/workspace/.next' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
at Server.readBuildId (/workspace/node_modules/next/dist/next-server/server/next-server.js:151:355)
at new Server (/workspace/node_modules/next/dist/next-server/server/next-server.js:3:120)
at NextServer.createServer (/workspace/node_modules/next/dist/server/next.js:1:2935)
at process._tickCallback (internal/process/next_tick.js:68:7)
I'm not sure how to resolve this though... Adding below my config files:
package.json
{
"main": "server.js", // my next.js app init file
"scripts": {
"dev": "FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 next dev",
"start": "next start",
"build": "next build",
"build:functions": "tsc",
"lint": "npm run lint:next && npm run lint:functions",
"lint:functions": "eslint --ext .js",
"lint:next": "next lint",
"deploy": "firebase deploy --only database,hosting,functions:nextServer",
"emulate": "firebase emulators:start --import=./emulator-data --export-on-exit",
"test": "jest --runInBand --detectOpenHandles",
"cypress": "cypress open"
},
"dependencies": {
// including next
}
}
firebase.json
{
"functions": {
"source": ".",
"runtime": "nodejs10",
"ignore": [
"**/.next/cache/**",
"**/__tests__/**",
"**/components/**",
"**/cypress/**",
"**/emulator-data/**",
"**/functions/**",
"**/layouts/**",
"**/node_modules/**",
"**/pages/**",
"**/public/**",
"**/utils/**",
"**/.*",
"**/*.log",
"**/cypress.json",
"**/database.rules.json",
"**/firebase.json"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build:functions"
]
},
"hosting": {
"target": "my_app",
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [{
"source": "**",
"function": "nextServer"
}]
}
}
I assume that, once deployed, Firebase Functions environment would run npm run build and npm run start scripts. Or is the workflow different? Perhaps my scripts are incorrect?
Similar to scripts in package.json files, the predeploy and postdeploy lines are executed before and after a call to firebase deploy when using the Firebase CLI (documented here).
When the Firebase CLI uploads your code to the Cloud Functions staging servers, it is expected to have already been compiled and only needs its runtime dependencies installed. Once an upload has completed, the staging server will execute npm install --production and then prepare your function to handle requests (essentially performing a cold-start, without actually executing the function). If either step fails, you will be shown an error like you have. If both steps succeed, your code with the dependencies installed is persisted as an image and saved to Cloud Storage, ready to use when requests to be handled come in.
In your case, the error seems to be that your .next folder is missing the compiled version of your application.
There are two possible causes of this, either your build prior to deployment is incomplete or when your files are uploaded, something in your ignore list that is required by the deployed code is missing.
For the first part, you modified the predeploy hook in my previous answer from:
{
"functions": {
"source": ".",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
...
}
incorrectly to:
{
"functions": {
"source": ".",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build:functions"
]
},
...
}
By changing this, you aren't building your next app prior to deploying the code to the staging server.
In regards to the second part, the deployed next application may be missing some of its dependencies - you can either fine tune the ignore list or you can perform the next build step on the server using a postinstall script in your package.json file:
{
"main": "server.js", // my next.js app init file
"scripts": {
...
"build:next": "next build",
...
"postinstall": "npm run build:next"
},
"dependencies": {
// including next
}
}
Note: If your main file is just JavaScript, you no longer need the typescript compile step defined in npm run build:functions and it can be removed.
I was this error, my solution was:
First, in the packege.json file, in the section scripts, we must modify the property “build”: "next build && next export", and a new property "export": "next export"
Second, we must establish the component and data folders in the root of the project
Third: use the command:
a)You must make log in, so type: firebase login
b)select de option "Configure files for Firebase Hosting and (optionally) set
up GitHub Action deploys"
c)in the question: if you have a build process
for your assets, use your build's output directory?
What do you want to use as your public directory?
You must type: out (really important, it's a folder output)
d) You must type: npm run build
f) last step: type: firebase deploy
package.json
out folder
Related
EDIT:
I want to deploy a Nuxt3 app to Firebase Hosting. I've set the deployment preset for Nitro to "firebase" NITRO_PRESET=firebase, and the build step works fine. However, when I run firebase deploy, I get an error saying:
There was an error reading .output/server/package.json:
.output/server/index.js does not exist, can't deploy Cloud Functions
I checked the .output/server directory, and saw that Nitro generated a file called index.mjs. I checked to see if Cloud Functions also works with .mjs files, but that doesn't seem to be the case. I looked for possible solutions but couldn't find anything; I tried reinstalling my modules, but no luck. Do I have something misconfigured or broken?
I'm following this tutorial:
https://nitro.unjs.io/deploy/providers/firebase
I'm using WSL2 Ubuntu on Windows 11, and the project folder is inside the linux filesystem.
Here is my package.json:
{
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview"
},
"devDependencies": {
"#nuxtjs/google-fonts": "^3.0.0-0",
"#types/three": "^0.143.1",
"nuxt": "3.0.0-rc.8"
},
"dependencies": {
"firebase": "^9.9.3",
"sass": "^1.54.5",
"three": "^0.143.0",
"vuex": "^4.0.2",
"sass-loader": "^13.0.2"
}
}
My firebase.json:
{
"functions": {
"source": "./.output/server",
"runtime": "nodejs16",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
},
"hosting": {
"site": "my-site",
"public": ".output/public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"cleanUrls": true,
"rewrites": [
{
"source": "**",
"function": "server"
}
]
}
}
After the build step:
Σ Total size: 19.6 MB (3.21 MB gzip)
✔ You can deploy this build using npx firebase deploy
After the deployment step:
i deploying functions, hosting
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
✔ functions: required API cloudbuild.googleapis.com is enabled
✔ functions: required API cloudfunctions.googleapis.com is enabled
✔ artifactregistry: required API artifactregistry.googleapis.com is enabled
i functions: preparing codebase default for deployment
Error: There was an error reading .output/server/package.json:
.output/server/index.js does not exist, can't deploy Cloud Functions
It seems you are using the default node-server preset. To deploy the Nuxt 3 app to Firebase, you must set the NITRO_PRESET to firebase in your environment.
NITRO_PRESET=firebase
npm run build
The CLI should prompt you to run npx firebase deploy once the build is completed.
Then run the command and it will deploy the application to Firebase hosting and functions.
You can read more about this in the documentation.
I am developing with Firebase Cloud Functions and testing on local emulators. I am using Typescript as my language.
However, whenever I update my code and hit save, the changes do not reflect in the emulator. I would always have to stop and re-run the emulator.
Is there a way where I could achieve this without having to stop and re-run?
Typescript supports a configuration file called tsconfig.json. In that file you can configure the compiler, define code formatting rules and more importantly for you, provide it with information about the TS files in your project. You have it watch the files for changes then you can use the 'watch' flag: tsc --watch inside your package scripts.
Script:
"scripts": {
"serve": "npm run build -- --watch | firebase emulators:start --only functions",
...
}`
A common tsconfig.json file:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"noLib": false
},
"include": [
"**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]}
I installed the Firebase Functions and Firestore emulators in my project with firebase init > emulators but now realize I don't need the Functions emulator any more so I'm trying to delete it.
How can I uninstall an emulator so that the firebase emulators:start command doesn't try to start it by default?
I tried the following but firebase init > emulators continues to show that the functions emulator is still enabled (green dot) and firebase emulators:start continues to start the functions emulator by default if I don't include the --only firestore flag.
I reran firebase init > emulators and deselected functions
This didn't do anything
I manually removed the entry from firebase.json
"emulators": {
"functions": { // <-- I removed this block
"port": 5001
},
"firestore": {
"port": 8080
},
"ui": {
"enabled": true
}
}
I cleared the emulator cache from ~/.cache/firebase/emulators
I removed the functions block from firebase.json just to see if that was triggering it.
{
"functions": { // <-- I removed this block
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run clean",
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"emulators": {
"firestore": {
"port": 8080
},
"ui": {
"enabled": true
}
}
}
After doing all of the above, firebase emulators:start still tries to start functions. I wondered if it might be because the firestore emulator depends on the functions emulator but if that were the case I don't know why it would let me run the firestore emulator alone with --only firestore
In my case, I deleted the Function directory from node_modules and I removed the functions block from firebase.json too.
I fixed it just running npm install firebase again.
If you don't want to use Cloud Functions in your project, you should remove the "functions" folder from your project directory as well.
Also, suggest that you file a bug for this on the firebase-tools GitHub. The fact that the functions emulator runs without configuration in firebase.json feels like a bug, and it didn't used to work that way.
I'm trying to set a target deploy for Firebase Functions.
https://firebase.google.com/docs/cli/targets
This is the firebase.json file
{
"functions": [{
"target": "production",
"source": "src/prod/functions",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}]
}
The predeploy runs normally but when deploying gets an error
functions[prod]: Finished running predeploy script.
Error: An unexpected error has occurred.
If I go to firebase-debug.log it shows:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
Putting the Functions folder on the project root it will deploy normally.
What is missing here?
Try running firebase init and set the options as best you can so it doesn't overwrite your existing project. I had to run it from the parent directory of /functions otherwise it will create a new directory but maybe there is some option to set a different directory name to suit your case.
From the link that you posted:
Firebase supports deploy targets for:
Firebase Hosting sites
Cloud Storage for Firebase storage buckets
Firebase Realtime Database instances
I was also looking for the same answer, but it seems that it is still not supported in the end of 2022
Trying to configure environment variables with firebase sdk. It contains a token which will be used in a google cloud function.
I've followed the docs to a tee and I get this error when I try to redeploy the cloud function.
I've got these at the top of my index.js file
const functions = require("firebase-functions");
const token = functions.config().slack.token;
This is my package.json file
{
"name": "quincygeorge",
"version": "1.0.0",
"description": "smart-office-assistant",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jonathan Puc",
"license": "ISC",
"dependencies": {
"firebase-admin": "^5.5.1",
"firebase-functions": "^0.7.3",
"slack": "^9.1.0"
}
}
As stated in the docs, I ran "firebase deploy --only functions" first before trying to run...
"gcloud beta functions deploy myfunction --stage-bucket mybucket --trigger-http"
again. But I still get this error.
My firebase tools and all the modules are up to date as I only installed them today.
The error message is complaining about your version of the Firebase CLI.
Update to the latest version. 3.16.0 at the time of this writing.
npm update -g firebase-tools