I have a cloud function that validates inputs from a form submission on my client. I'm using Cloud Functions for Firebase https triggers with cors express middleware.
Firebase Function
const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors')({origin: true});
const validateImageForm = require('./library/validate-image-form');
exports.apiValidateImageForm = functions.https.onRequest((req, res) => {
cors(req, res, () => {
validateImageForm(req.body.formInputs, req.body.imageStatus).then((data) => {
res.status(200).send(data);
});
});
});
Client Call To Function
const validateImageFormFetchOptions = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: 'POST',
body: JSON.stringify({
formInputs: formInputs
})
}
fetch('https://project-url.cloudfunctions.net/apiValidateImageForm', validateImageFormFetchOptions)
.then(response => response.json())
.then(serverErrors => {console.log(serverErrors)});
Issue
When I call this function from my client using a fetch request I see two apiValidateImageForm triggers in the functions logs. The first is a status 204 and I assume this comes from the cors preflight request that checks the origin. The final request is status 200. I just want one function trigger when I fetch the apiValidateImageForm function. I'm concerned that over time the preflight requests that output the status 204 will add unnecessary function calls to my project quota.
Question
Is it possible to prevent firebase from triggering a function call on the preflight request? If not then is there a way to prevent the preflight request and successfully pass data to the function.
Requests on your Firebase Hosting site can be proxied to specific HTTP functions. This also allows you to use your own custom domain with an HTTP function.
You can enable CORS by installing cors library in your functions folder: npm i cors --save Here is an example of usage: const functions = require('firebase-functions'); const cors = require('cors'); exports.addMessage = functions.https.onRequest((req, res) => { cors() (req, res, () => { return res.json({status: 'ok'}); }); });
Please try again later. Cloud Functions for Firebase is a serverless framework that lets you automatically run backend code in response to events triggered by Firebase features and HTTPS requests. Your JavaScript or TypeScript code is stored in Google's cloud and runs in a managed environment.
The URL includes the following, in order: The region (or regions) to which you deployed your function. Some production functions may need to explictly set the locationto minimize network latency. Your Firebase project ID
The Firebase CLI creates a .zip archive of the function code, which is then uploaded to a Cloud Storage bucket (prefixed with gcf-sources) in your Firebase project. Cloud Build retrieves the function code and builds the function source.
To fix the duplicate requests 200 and 204 then change how you're client side fetch request. @sideshowbarker is right. The browser automatically does the CORS preflight OPTIONS request so this is not an issue in Cloud Functions for Firebase. This answer was helpful.
To fix the preflight I changed my code to the following:
Client Call To Function
Removed the headers from the fetch options completely rather than setting the content type as application/json. By default the fetch request content type is application/x-www-form-urlencoded; charset=UTF-8.
const validateImageFormFetchOptions = {
method: 'POST',
body: JSON.stringify({
formInputs: formInputs
})
}
fetch('https://project-url.cloudfunctions.net/apiValidateImageForm', validateImageFormFetchOptions)
.then(response => response.json())
.then(serverErrors => {console.log(serverErrors)});
Firebase Function
Explicitly parsed the request body because it is now received as a text string.
const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors')({origin: true});
const validateImageForm = require('./library/validate-image-form');
exports.apiValidateImageForm = functions.https.onRequest((req, res) => {
cors(req, res, () => {
const body = JSON.parse(req.body);
validateImageForm(body.formInputs, body.imageStatus).then((data) => {
res.status(200).send(data);
});
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With