Reputation: 65
Really new to firebase and very junior level at code. I am trying to figure out a bug where a custom 404 is not showing, or when rewrites changed then app does not work.
"rewrites": [
{
"source": "**",
"function": "app"
}
]
This redirects everything to the app and app functions properly. However, the 404.html doesn't show if a bad URL is attempted. There is a generic "Cannot GET /asdfasd"
Changed it to
"rewrites": [
{
"source": "/",
"function": "app"
}
]
This will now show the custom 404.html properly.
However, with this a function responds with 404 with this configuration, breaking the app. From functions/index.js:
app.post('/sendsmstoconsumer', (request, response) => {
client.messages
.create({body: request.body.message, from: '+15555555555', to: request.body.phone})
.then(message => {
response.send("Your message: " + request.body.message + " has been sent!")
});
})
I have tried a number of variations like below, but I'm just missing something.
{
"source": "/",
"function": "app"
},
{
"source": "/sendsmstoconsumer",
"function": "sms"
}
]
change functions/index.js:
exports.sms = functions.httpsOnRequest((request, response) => {
client.messages
.create({body: request.body.message, from: '+15555555555', to: request.body.phone})
.then(message => {
response.send("Your message: " + request.body.message + " has been sent!")
});
})
I would appreciate any help with the proper way to structure the rewrite, or change the function both the custom 404 and app work properly. I seem stuck with getting either one or the other.
Thank you.
As requested, editing to add the complete files:
firebase.json
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "app"
}
]
},
"emulators": {
"functions": {
"port": 5001
},
"database": {
"port": 9000
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
}
}
}
index.js
const functions = require('firebase-functions')
const express = require('express')
const app = express()
const accountSid = 'xxx'
const authToken = 'xxx'
const client = require('twilio')(accountSid, authToken)
const cors = require('cors')
// Enable cors for everything
// TODO: Re-enable cors at a later date
// src: https://www.npmjs.com/package/cors
app.use(cors())
app.post('/sendsmsverificationmessage', (request, response) => {
client.verify.services('xxx')
.verifications
.create({to: request.body.phone, channel: 'sms'})
.then(verification => {
response.send("Your verification code has been sent to your phone!" )
});
})
app.post('/verifyusersphonenumber', (request, response) => {
client.verify.services('xxx')
.verificationChecks
.create({to: request.body.phone, code: request.body.token})
.then(verification_check => {
response.send("Your phone has been verified!")
});
})
app.post('/sendsmstoconsumer', (request, response) => {
client.messages
.create({body: request.body.message, from: '+15555555555', to: request.body.phone})
.then(message => {
response.send("Your message: " + request.body.message + " has been sent!")
});
})
exports.app = functions.https.onRequest(app)
Upvotes: 0
Views: 570
Reputation: 65
Thanks to Michael Bleigh's answer, we found a solution, but had to specify the 404.html file.
app.use((req, res) => {
res.set('X-Cascade', 'PASS')
res.status(404).redirect('404.html')
})
Upvotes: 1
Reputation: 26333
By default a rewrite does not "fall through" once matched, so the response sent by the Cloud Function will always be returned directly to the user. There is actually a way to get around this: if your response body includes a header of X-Cascade: PASS
.
In this case, Firebase Hosting will fall through to the default 404 behavior (including a custom 404.html). You should be able to add this to your Express app like so:
// *AFTER* all other endpoints
app.use((req, res) => {
res.set('X-Cascade', 'PASS');
res.status(404).send('Not Found');
});
Upvotes: 1