I have used firebase functions with node js before and consistently run similar functions as below. However, I am now getting this error all of a sudden in my console:
Access to fetch at 'https://us-central1-myapp.cloudfunctions.net/test2' from origin 'http://localhost:8383' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
POST https://us-central1-myapp.cloudfunctions.net/test2 net::ERR_FAILED
This is my code I don't know what I am doing wrong:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const nodemailer = require('nodemailer');
const {Storage} = require('@google-cloud/storage');
var PizZip = require('pizzip');
var Docxtemplater = require('docxtemplater');
admin.initializeApp();
const BUCKET = 'gs://myapp.appspot.com';
const cors = require('cors');
const https = require('https');
const express = require('express');
const app = express();
app.use(cors({origin: true}));
const storage = new Storage({
projectId: 'myapp' });
// The error object contains additional information when logged with JSON.stringify (it contains a properties object containing all suberrors).
function replaceErrors(key, value) {
if (value instanceof Error) {
return Object.getOwnPropertyNames(value).reduce(function(error, key) {
error[key] = value[key];
return error;
}, {});
}
return value;
}
function errorHandler(error) {
console.log(JSON.stringify({error: error}, replaceErrors));
if (error.properties && error.properties.errors instanceof Array) {
const errorMessages = error.properties.errors.map(function (error) {
return error.properties.explanation;
}).join("\n");
console.log('errorMessages', errorMessages);
// errorMessages is a humanly readable message looking like this :
// 'The tag beginning with "foobar" is unopened'
}
throw error;
}
function readStreamToBuffer(stream) {
return new Promise((resolve, reject) => {
const chunkArray = [];
stream
.on('data', (chunk) => chunkArray.push(chunk))
.on('error', (err) => {
chunkArray = [];
reject(err);
})
.on('end', () => {
const buffer = Buffer.concat(chunkArray);
chunkArray = [];
resolve(buffer);
});
});
}
exports.test2 = functions.https.onCall(async(data, context) => {
const file_name = 'tag-example.docx';
const storageRef = storage.bucket(BUCKET).file(file_name);
const buffer = await readStreamToBuffer(storageRef.createReadStream());
const zip = new PizZip(buffer);
let doc;
try {
doc = new Docxtemplater(zip);
} catch(error) {
// Catch compilation errors (errors caused by the compilation of the template : misplaced tags)
errorHandler(error);
}
doc.setData({
first_name: 'Fred',
last_name: 'Flinstone',
phone: '0652455478',
description: 'Web app'
});
try {
doc.render();
} catch (error) {
errorHandler(error);
}
const contentBuffer = doc.getZip()
.generate({type: 'nodebuffer'});
console.log(doc);
const targetStorageRef = storage.bucket(BUCKET).file("compiled.docx");
await targetStorageRef.put(contentBuffer);
});
Is there someway to get that error that shows up in my client side console to go away and my cloud function to run? any help will be appreciated



First thing that I notice is you are using callable cloud functions but the express app is using the cors middleware here:
app.use(cors({origin: true}))and there no routes in that app. I don't think you need to explicitly import express and CORS when using callable functions so try removing them. Quoting from here, "CORS should be automatically handled by the onCall handler".If you want to use Express and CORS middleware like that, you should try onRequest functions as shown below:
Now in this case the CORS middleware you wrote will be running. Your function's URL may look something like -
https://us-central1-myapp.cloudfunctions.net/apiThen to use the/test2route it becomeshttps://us-central1-myapp.cloudfunctions.net/api/test2. CORS shouldn't be an issue anymore here but do note it's an express app now so the parameters in the function areRequest, Responseinstead ofdata, context.Additionally, I see your are calling the API from localhost so using Firebase Functions Emulator may be a good idea. To use specify to use the emulator like this:
firebase.functions().useFunctionsEmulator('http://localhost:5001')