Recently I was working on a small test project where I wanted to call a Firebase Cloud Function directly from my Nuxt.js frontend using fetch. It all looked straightforward until I ran into one of the most dreaded frontend errors:
Even though my Cloud Function worked perfectly when tested in the Google Cloud Console, every call from my website failed with the usual CORS wall. After a lot of debugging (and frustration), I finally figured out what was going wrong. Let me walk you through the problem, the fix, and what I learned.
The Setup
I had a simple Firebase Function in index.js:
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });
admin.initializeApp();
exports.askQuestionIntent = functions.https.onRequest(async (req, res) => {
return cors(req, res, async () => {
console.log("yeeeeeee");
});
});
And I called it from my Nuxt store action like this:
export const actions = {
async askQuestion({ commit, state }, value) {
const firebaseRest =
"https://us-central1-abc.cloudfunctions.net/askQuestionIntent";
let res = await fetch(firebaseRest, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(value),
});
let data = await res.json();
console.log(data);
},
};
But whenever I ran it from my actual deployed website, the browser threw this at me:
Access to fetch ... from origin ... has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
So What Was the Real Issue
Even though I had cors imported and wrapped inside my function, I wasn’t actually responding to the request. Returning from the CORS wrapper without calling res.status(...).json(...) or at least res.send(...) causes Firebase to end the function prematurely which means no CORS headers are sent back to the browser, and the browser blocks it.
On top of that, because I was using a POST request, the browser automatically performs a preflight OPTIONS request before sending the real payload. If that OPTIONS request isn’t handled properly, it fails before your function even runs.
The Fix
Here’s the correct and complete version of the Firebase function:
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });
admin.initializeApp();
exports.askQuestionIntent = functions.https.onRequest((req, res) => {
cors(req, res, () => {
if (req.method === "OPTIONS") {
res.set("Access-Control-Allow-Methods", "POST");
res.set("Access-Control-Allow-Headers", "Content-Type");
return res.status(204).send(""); // Preflight OK
}
console.log("Received request:", req.body);
return res.status(200).json({ message: "Success!", data: req.body });
});
});
Final Thought
The lesson here Wrapping a Firebase Function with CORS isn’t enough you must still send a response, otherwise the CORS headers are never applied. And if you’re making a POST call, don’t forget about the OPTIONS preflight! Once I handled both properly, my Nuxt frontend worked instantly without changing a single line in the fetch call. If you’re stuck with mysterious CORS errors even though “everything looks right”, double-check whether your function actually responds. Silence is not golden when it comes to HTTP.

