2
votes

I have a function that i need to return a list of users after calling an API (firebase function). I am using express CORS on the server to allow requests from local host.

The issue I am having is that the CORS preflight is returning a 204 with no response before my data (which I know is expected for pre flight to fire first) but it (or Fiebase SDK) is throwing an error because 204 was returned with 'no response' so my then function never receives the data. The data is actually received in the 200 response after the CORS response but by then it's too late. The error shown in console is

Error: Response is missing data field.

The code is:

return firebase.functions().httpsCallable('listUsers')().then((users) => {
  // pre-flight cors check means this doesnt return users due to the error
  console.log(users);
  return users;
}).catch(function (error) {
  console.error("Error getting document: ", error);
});`

But in network tab I have 204 and 200 with expected result. Anyone experienced this with firebase and cors?

2
CORS is a mechanism that a server uses to allow a third party to access its resources. If the server isn't allowing you to access its resources, then contact the owner of the server to find out how you can gain access to their resources correctly - it may mean you need to proxy any requests to their server using your own server, as server side requests are not subject to CORSJaromanda X
The thing is i get two responses from the server one for pre flight and one for the actual body with data. Cors returns first without any response and triggers an undefined error in code. That's the issue I have. Never seen this behaviour. First time working with firebase I think it may be that.Eden WebStudio
thanks@JaromandaX. This is certainly a strange one with firebase sdk. Their source code throws the error because I did not assign the json body being returned with data as the variable name. It for some reason enforces {data: []}. So while it appear as a CORs issue it wasnt.Eden WebStudio
github.com/firebase/firebase-js-sdk/issues/1338 other had the same issue. Their docs dont mention that though in the HTTP functions section.Eden WebStudio
fair enough, so 204 status is actually OK (the internet seems divided on this as there was perhaps years ago a bug in Chrome when preflight returned 204) I've removed my comments regarding 200 vs 204 in preflight response so a not to confuse future readers :pJaromanda X

2 Answers

1
votes

When you make an http request, you must always send a response. Here's an example I use, already with cors, to work properly with your front end.

Return response in data field. Ex: res.send({data:users})

//file: gustavodamazio.ts or index.ts

import * as functions from "firebase-functions";

const cors = require("cors")({ origin: true });

export const nome_funcao = functions.https.onRequest((req, res) => {
    return cors(req, res, () => {
        return res.status(200).send({ data: resData });
    }
}

DOC: https://firebase.google.com/docs/functions/http-events

1
votes

I've been smashing my head against a brick wall for about 5 hours because of this. Thanks to the comments here I've finally got to the bottom of it - and not have to bugger around with CORS too. :)

I'm using VueJS. Here's a snippet of code that - based on the above - I got working.

This code goes in your component to call the Cloud function

// call this within an async function
const myfunc = firebase.app().functions().httpCallable('myfunc')
const resp = await myfunc({key: 'value'})
console.log({value: resp.data.key})

This code goes in your Cloud function file. I omit the imports for brevity

// echos back the data given
exports.myfunc = functions.https.onRequest(req, res) => {
  res.send({data: req.body.data})
  return null // ensure function exits once finished
}

The key part is to "wrap" the response in { data: } object. If you just send the data back "raw" the Cloud function will fail, complaining about CORS.