How to deploy ISR build folder in next js to firebase? I migrate from ssg to isr, currently, I deploy the out folder with export method. Now when I remove (export method (does not support ISR (getStatichPath fallback: true right?) firebase can't detect the index folder...
Any tutorial? How to deploy nextjs with Incremental Static Regeneration? ISR?
What I know is firebase deploy from out folder (SSG)
Firebase settings:
{
"hosting": {
"cleanUrls": true,
"public": "out/",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
"storage": {
"rules": "storage.rules"
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
}
}
Incremental Static Regeneration (ISR) is working out of the box with firebase even with a revalidate option.
Make sure to follow the guidelines for the firebase/nextjs setup.
export const getStaticProps: GetStaticProps = async () => {
const props: Props = {
updatedAt: new Date().getTime(),
};
return {
props: props,
revalidate: 10, // number of seconds to regenerate the page
};
};
Once deployed (yarn deploy), data will be updated every 10 seconds
Related
I am using NextJs 13 with experimental feature of "appDir"
while deploying to firebase hosting, dynamic routes become static path.
for example :
path app/[slug]/page.jsx become http://example.web.app/[slug]
You can see [slug] is consider as static page
Steps to reproduce
create nextjs13 app npx create-next-app#latest --experimental-app
create app/[slug]/page.jsx.
enable firebase experiments:enable webframeworks
make sure to enable billing.
firebase init hosting then firebase deploy
after successfully deployment, check http://your-domain.web.app/hello, you will see page not found but http://example.web.app/[slug] is working.
in firebase.json
{
"hosting": {
"source": ".",
"cleanUrls": false,
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
in next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
},
}
module.exports = nextConfig
in jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#/*": ["./*"]
}
}
}
I started a Quasar V2 app using the quasar CLI with vite config and ssr build. I can't seem to return the firebase functions handler from dist/ssr/index.js as suggested in the docs.
I've tried this with the webpack Quasar V2 config and it works fine.
I ran firebase init then installed firebase-functions and firebase-admin in the root dir.
I changed the source of functions to dist/ssr where I built my ssr app. I also edited hosting to send requests to the function "handler".
firebase.json
"functions": {
"source": "dist/ssr",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
},
"hosting": {
"public": "dist/ssr",
"rewrites": [
{
"source": "**",
"function": "handler"
}
],
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
},
I then returned the handler function, following the instructions from the quasar docs
server.js
import * as functions from "firebase-functions";
export const listen = ssrListen(async ({ app, port, ssrHandler }) => {
if (process.env.DEV) {
await isReady();
return app.listen(port, () => {
if (process.env.PROD) {
console.log("Server listening at port " + port);
}
});
} else {
return {
handler: functions.https.onRequest(ssrHandler),
};
}
});
I then ran "npm install" on both the root directory and the dist/ssr directory to make sure everything is fine.
then when I ran "firebase serve" I get back this result in localhost:5000 "Function us-central1-handler does not exist, valid functions are:" Whats going on :(
Setting
I am developing on a test Firestore instance hosted on firebase, and I would like to run firebase emulators:start targeting this database. Currently it's targeting an emulator suite accessible through localhost:4000. In the codebase, I have initialized firebase instance with parameters for the actual instance as follows:
const fireAdmin = admin.initializeApp({
credential : admin.credential.applicationDefault()
, databaseURL : DatabaseConfig['databaseURL']
, storageBucket: DatabaseConfig['storageBucket']
});
where DatabaseConfig = { databaseURL: "https://mytestingserversite.firebaseio.com", ... }.
Problem
However, the functions are still writing/reading from the emulator instance. This is my firebase.json:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"hosting": {
"rewrites": [
{
"source": "**",
"function": "app"
}
]
},
"functions": {
"source": "functions"
},
"emulators": {
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
}
}
}
Am I missing some env variable here?
The databaseURL parameter isn't really doing something here, as it is for specifying the Realtime Database URL.
Regardless of which emulator you are actually using, you can omit the Firestore emulator by just running the emulators you want.
For instance: firebase emulators:run --only functions,hosting
That should tell the CLI to use the actual Firestore instance in the Cloud and not the emulator.
I'm having trouble deploying my quasar project to Firebase. It says the deployment was successful, but after two hours, this is what shows up on the webpage.
firebase.json
"hosting": {
"public": "dist/spa",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
routes.js
const routes = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('pages/PageUsers.vue') },
{ path: '/chat/:otherUserId', component: () => import('pages/PageChat.vue') },
{ path: '/auth', component: () => import('pages/AuthPage.vue') }
]
},
// Always leave this as last one,
// but you can also remove it
{
path: '*',
component: () => import('pages/Error404.vue')
}
]
export default routes
I first ran quasar build, then firebase init, then firebase deploy yet nothing is showing up on the site yet. Any ideas to why this is happening?
Update: Now the same page is showing on http://localhost:8080/ instead of my project as well
If you build first, "firebase init" will overwrite your index.html.
Firebase init
Run quasar build
Firebase deploy
Did you try in this order?
I also had the same problem but, after I changed the order, then it worked as usual.
It is because Firebase is overwriting your index.html with its own index.html, to fix that:
run quasar build -m spa to generate the correct index.html
run firebase init and when it asks you to overwrite index.html select 'No' like this:
run firebase deploy
I ran into the same issue while setting up Quasar project with Firebase hosting.
One thing I noticed was there was a new index.html generated during firebase init inside the public folder.
After deleting public/index.html, the original index page displays properly.
Solution:
Check if there is an index.html file generated in public folder
Delete the file
Update: My approach to use 2 folders: functions and src in not working. I started to use another approach when folder for firebase functions is located inside of the src folder. This approach is implemented by winzaa123 user: winzaa123/nuxt2-vuetify-ssr-on-firebase and I could launch it on my Google firebase.
My Steps: Preparation of the project from scratch
Create a Nuxt app inside of the src folder:
Create a Nuxt app in src folder with create-nuxt-app src
Choose the package manager Npm
Choose UI framework Vuetify.js
Choose rendering mode Universal (SSR)
Create a Firebase Project
Create a Firebase project with firebase init
Select Firebase Hosting, Firebase Functions, Firebase Firestore, Firebase Storage, Emulators
Use public directory? (public)
Configure as a single-page app (y/N) - Yes
Create a package.json file in the root folder
{
"name": "test-nuxt",
"version": "1.0.0",
"description": "My fine Nuxt.js project",
"author": "Alex Pilugin",
"private": true,
"scripts": {
"postinstall": "cd functions && npm install",
"dev": "cd src && npm run dev",
"start": "cd src && npm run dev",
"serve": "NODE_ENV=development firebase serve",
"build": "cd src && npm run build",
"build-deploy": "firebase deploy --only hosting,functions",
"build-deployf": "firebase deploy --only functions",
"build-deployh": "firebase deploy --only hosting"
},
"dependencies": {
"nuxt": "^2.0.0"
},
"devDependencies": {
"#nuxtjs/vuetify": "^1.0.0"
}
}
Edit firebase.json file
{
"functions": {
"source": "functions",
"predeploy": [
"rm -rf functions/nuxt && npm --prefix src run build && mkdir -p functions/nuxt/dist && cp -r src/.nuxt/dist/ functions/nuxt/dist && cp src/nuxt.config.js functions/"
]
},
"hosting": {
"public": "public",
"predeploy": [
"rm -rf public/* && mkdir -p public/_nuxt/ && cp -r functions/nuxt/dist/client/ public/_nuxt/ && cp -a src/static/. public/"
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "nuxtssr"
}
]
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules"
}
}
You can see that I plan to copy content of the src/.nuxt/dist/client into the public/_nuxt folder.
I am doing it since I found "publicPath": "/_nuxt/" inside of the src/.nuxt/dist/server/client.manifest.json
Nest Step is editing of the functions/index.js file
const functions = require('firebase-functions');
const { Nuxt } = require("nuxt");
//const { Nuxt } = require("nuxt-start");
const config = {
ssrLog: true,
dev: true, // Don't start in dev mode.
debug: true, //<----------------------- Debug logs
buildDir: "nuxt",
build: {
//publicPath: ''
//publicPath: '/_nuxt/', //Default: '/_nuxt/' <-- content of .nuxt/dist/client
/*
** You can extend webpack config here
*/
extend ( config, { isDev, isClient, isServer } ) {
if ( isServer ) {
config.externals = {
'#firebase/app': 'commonjs #firebase/app',
'#firebase/firestore': 'commonjs #firebase/firestore',
//etc...
}
}
}
}
}
const nuxt = new Nuxt(config);
let isReady = false;
async function handleRequest(req, res) {
console.log("nuxtssr is running...");
if (!isReady) {
console.log("isReady: " + isReady);
try {
console.log("waiting for nuxt.ready().......");
isReady = await nuxt.ready();
console.log("nuxt is ready");
} catch (error) {
console.log("ERROR.....................");
console.log(error);
//throw new functions.https.HttpsError('error in Nuxt', error);
process.exit(1);
}
}
console.log("waiting for nuxt.render().......");
/*
* res.set('Cache-Control', 'public, max-age=1, s-maxage=1');
* await nuxt.render(req, res);
*/
res.set("Cache-Control", "public, max-age=300, s-maxage=600");
return new Promise((resolve, reject) => {
console.log("before nuxt.render......");
nuxt.render(req, res, promise => {
console.log("inside nuxt.render......");
promise.then(resolve).catch(reject);
});
});
}
exports.nuxtssr = functions.https.onRequest(handleRequest);
I use $ npm start to launch the application locally:
Nuxt.js v2.12.2
Running in development mode (universal)
Listening on: http://localhost:3000/
I deploy the application using $ firebase deploy command but I cannot see any Frontend. My application is hanging.
From my understanding, firebase hosting is only for static files. If you're trying to do SSR, that implies that there's a server running and some processing happening on the server side. You may need to deploy this to Google Cloud Functions as a "serverless" app. Take a look at this tutorial for an example.
That said, I'm not super familiar with Nuxt, but I can see two things you potentially need to do differently if you are, indeed, deploying to the correct place.
First, the hosting.public property in firebase.json should be the path to the folder that contains your built project. Since you've said your project is being built in public/_nuxt, you might need to change this property to match, i.e. in firebase.json have
{
...
"hosting": {
"public": "public/_nuxt",
...
},
...
}
For what it's worth, in regular (i.e. non-Nuxt) Vue projects, the project gets built in the dist/ folder, so in my firebase.json file I have "public": "dist". That said, I haven't ever hosted a Nuxt SSR project on firebase so this may not be how it is structured.
Second, you likely need to run nuxt build or nuxt generate before you run firebase deploy so that the project is built to the target directory. The firebase deploy command really is just a fancy way to upload files onto Google's platform.
Hope this helps!