Home > Enterprise >  Local Emulator Firebase Cloud Function Cannot Get and 404
Local Emulator Firebase Cloud Function Cannot Get and 404

Time:08-27

I want to be able to trigger a Firebase Cloud Function locally using the emulator. However, the function always returns 404 Not Found as status code and Cannot Get as response body. For context the function gets deployed locally (i.e you can see it on the UI), but when you hit it it returns the error described above.

It deploys to this endpoint http://localhost:5001/project/region/health and the command I'm running is firebase emulators:start --only functions

// app.ts
import * as express from 'express';
import * as functions from 'firebase-functions';
import { router as healthRouter } from './api/utils/router';

const healthApp = express();

healthApp.use('/health', healthRouter);

export = {
  health: functions.region('northamerica-northeast1').https.onRequest(healthApp),
};
// router.ts
import { Router } from 'express';
import { health } from './health';

export const router = Router();

router.get('/', health);
// health.ts
import type { Request, Response } from 'firebase-functions';
import * as functions from 'firebase-functions';

export const health = functions.https.onRequest(
  (req: Request, res: Response) => {
    res.status(200);
  }
);
// tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "outDir": "lib",
    "sourceMap": true,
    "strict": true,
    "target": "es2017",
    "allowSyntheticDefaultImports": true
  },
  "compileOnSave": true,
  "include": [
    "src"
  ]
}

CodePudding user response:

When you export an express app through Firebase Function, the paths become relative to the exported function name. You exported the app as exports.health which sets the root path of your function to /health and to call it, you would visit http://localhost:5001/project/northamerica-northeast1/health.

However, because you defined a route handler for /health (using router.get("/health", healthRouter)) as well, you added a handler for http://localhost:5001/project/northamerica-northeast1/health/health instead.

The error Cannot GET / is thrown because when you call the function at ttp://localhost:5001/project/northamerica-northeast1/health, the relative URL is set as "/", which you haven't configured a handler for (using router.get("/", healthRouter)).

To fix your code above, change your code to this:

router.ts:

router.get('/', health);

app.ts:

healthApp.use('/', healthRouter);

health.ts:

export const health = functions.https.onRequest(
  (req: Request, res: Response) => {
    res.send('Hello World!')
    res.status(200)
  }
);

This would return status: 200 and a response of Hello World!. Also, make sure that you run npm run build before running firebase emulators:start --only functions

  • Related