firebase-functions: `Cannot GET null` when using an Express app in HTTP functions
It seems that when passing an expressJS app to an HTTP function we cannot hit the “root” URL of the function https://us-central1-app-name.cloudfunctions.net/functionName when we do we get the following error:
Cannot GET null
This despite setting a handler for all URLs for instance:
const functions = require('firebase-functions');
const express = require('express');
const app = express();
app.get('*', (req, res) => {
res.send('Hello world');
});
exports.helloWorld = functions.https.onRequest(app);
Adding a trailing slash works. For instance: https://us-central1-app-name.cloudfunctions.net/functionName/ works normally.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 21
- Comments: 56 (7 by maintainers)
Got this to work for me previously:
https://gist.github.com/cdock1029/9f3a58f352663ea90f8b9675412c4aea
@team:
I arrived here from the comment in the example-functions, getting the ‘apply’ error and using the Router object. I fixed it using @cdock1029 patch.
Hello everyone - this issue has now been fixed for all Node runtimes >= 8 - see the public https://b.corp.google.com/issues/122944969. Thanks for everyone’s patience!
@sarovin that won’t work if you have query params in the request. Scroll up and use my solution which checks
path
and prepends/
to the url.Here is how I’ve been getting around the issue.
Lets say the deployed function should be myfunc:
@anlexN
Why are you angry?
Did you try the workaround I provided above? You can just splint that in front of your express app and it will work as expected (until a permanent fix is applied by Google Cloud). And even after that, it will continue to work because it only addresses the issue if the issue is present.
The http triggered Google Cloud Functions aren’t providing an express app, its providing a node.js request/response endpoint. Express is used under the hood to manipulate the req/res before you get it in your function, but the service isn’t actually intended to behave like an Express.Router. We are sort of bolting that functionality on top of it.
You might notice that body parsing is already done for you as well… Again, they are providing an endpoint and the server processing the routing is using STRICT routing, thats why leaving the slash off doesn’t work.
For the Google Cloud Functions team to fix this, they will probably need to disable STRICT routing in the enclosure that actually provides us with the req/res endpoint.
In the meantime, try this pattern: https://github.com/firebase/firebase-functions/issues/27#issuecomment-451451749
Hey everybody, I just solved this problem under somebody’s help, and like to share back to everyone, the
key
to solve this issue perfectly is that you need to fix thereq.url
BEFORE express app handler is called. If yourfix code
inside the express app handler, it has no chance to be called whenmissing end / 404 error
happen AFTER deployed (but it works fine when you testing locally by runningfirebase serve --only hosting,functions
orfirebase experimental:functions:shell
), here the hero’s message on Firebase Slack - functions channelAlso I paste the screenshot here, make sure you can see that if not join the Firebase Slack - functions channel yet:
@JulienMalige You are welcome, and also correct. I found this link that details using a similar method with Express: https://codeburst.io/express-js-on-cloud-functions-for-firebase-86ed26f9144c See: “An Automated Solution”
It is very much what @cdock1029 shared previously. Seems req.path is not important for this, but I noticed that the example does not check if req.url IS defined, but missing the proceeding slash “/”. That seems to make a difference later in routing when a query string is included.
One other note: While the functions emulator appears to allow HTTP DELETE methods with a request body, in production, the live cloud functions do not seem to acknowledge that DELETE methods might have a request body. Even reapplying the bodyParser middleware doesn’t seem to work.
this is caused by the empty value of
req.url
when hitting https://us-central1-app-name.cloudfunctions.net/functionNameHaving read a bit online it seems that this is not an expected value for ExpressJS nor NodeJS. req.url should at least be
'/'
:https://github.com/expressjs/express/issues/2281#issuecomment-70447144
Basically
req.url
should never be an empty String. We should always have to to be'\'
when requesting https://us-central1-app-name.cloudfunctions.net/functionNameAnd while we are at it,
baseUrl
andoriginalUrl
should probably be ‘/functionName’ instead of ‘’Original report for reference: https://github.com/firebase/functions-samples/issues/101