0
votes

I am working on a project using the Vercel Next.js firebase-with-hosting template found here.

The template uses a Firebase Function to allow for Firebase Hosting. I am trying to add additional Firebase onRequest functions so that I can send request to the server.

I've added the printTest function and set the rewrites in the firebase.json file but keep getting 404 errors. I've successfully implemented this before with Express and without NextJS. I think I have an issue with my rewrites.

I've also tested onCallable, and pubSub functions and these worked great. My guess is I have a rewrite issue. Any help with understanding why this does now work would be greatly appreciated.

const { join } = require('path'); // From NextJS Vercel Base Build
const { default: next } = require('next'); // From NextJS Vercel Base Build
const isDev = process.env.NODE_ENV !== 'production'; // From NextJS Vercel Base Build
const nextjsDistDir = join('src', require('./src/next.config.js').distDir); // From NextJS Vercel Base Build
const admin = require('firebase-admin'); // Firebase Admin SDK for NodeJS.
const functions = require('firebase-functions'); // For NextJS + Firebase Functions + Firebase Hosting.
const serviceAccount = require('./firebaesAdminServiceAccountKey.json'); // Service account key for Firebase Admin SDK.
    
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++ Firebase Admin Initialization ++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
});
    
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++ Firebase Firestore Initialization ++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
const dba = admin.firestore();
    
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++ Nextjs Configuration ++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
const nextjsServer = next({
    dev: isDev,
    conf: {
        distDir: nextjsDistDir,
    },
});
    
const nextjsHandle = nextjsServer.getRequestHandler();
    
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++ Cloud Functions ++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
// Nextjs Cloud Function to allow for Firebase Hosting.
exports.nextjsFunc = functions.https.onRequest((req, res) => {
    return nextjsServer.prepare().then(() => nextjsHandle(req, res));
});
    
exports.printTest = functions.https.onRequest((req, res) => {
    console.log('THIS WORKS!');
    res.status(200).send();
});

Here is the firebase.json file with the rewrite.

{
    "hosting": {
        "public": "public",
        "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
        "rewrites": [
          {
            "source": "**",
            "function": "nextjsFunc"
          },
          {
            "source": "/printTest",
            "function": "printTest"
          }
        ]
    },
    "functions": {
        "source": ".",
        "predeploy": [
          "npm --prefix \"$PROJECT_DIR\" install",
          "npm --prefix \"$PROJECT_DIR\" run build"
        ],
        "runtime": "nodejs10"
    }
}
1

1 Answers

1
votes

The URL pattern ** means that all of your requests are sent to nextjsFunc() and that includes /printTest. Since that is the first rewrite config rule, anything below is ignored.

From the doc, here's an important note:

Hosting applies the rewrite defined by the first rule with a URL pattern that matches the requested path. So, you need to deliberately order the rules within the rewrites attribute.

Fix the issue by changing the order and putting the least-strict rule at the end:

"rewrites": [
  {
    "source": "/printTest",
    "function": "printTest"
  },
  {
    "source": "**",
    "function": "nextjsFunc"
  }  
]