5
votes

I have a deployed a cloud function which looks like this:

export const publishVersion = functions
  .region("europe-west2")
  .https.onCall(async (data, context) => {}

Then in my web client I am defining a function to call it like this:

import { functions } from "firebase";

const callPublishVersion = functions().httpsCallable("publishVersion");

export function publishVersion(
  guidelineId: string,
  guidelineReference: string
) {
  return callPublishVersion({
    id: guidelineId,
    reference: guidelineReference
  });
}

Note that the only reason I wrap the function is to have strict typing in my client, but that's besides the point of this question.

The problem is, if I run the web client on a local server (localhost) and call the function, two things seem to go wrong. I get a CORS error:

Access to fetch at 'https://us-central1-my-project.cloudfunctions.net/publishVersion' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

And also it looks like it is trying to communicate with us-central1 even though my functions are deployed to europe-west2. When I deploy firebase-tools tells me what the url should be:

✔ functions[publishVersion(europe-west2)]: Successful create operation. Function URL (publishVersion): https://europe-west2-baymard-gemini-dev.cloudfunctions.net/publishVersion

Where/how do I control things to prevent this CORS error and how can I direct httpsCallable to a different region?

The official documentation does not mention any of this.

--- edit ---

I just found out that if I deploy the function to us-central1 it works without errors. So the CORS part is not an issue (I'll remove it from the title) and the question becomes: How do I configure the web client to call the right region?

--- edit ---

I noticed this in the docs:

Note: To call a function running in any location other than the default us-central1, you must set the appropriate value at initialization. For example, on Android you would initialize with getInstance(FirebaseApp app, String region).

Which seems to be a good pointer, but I don't see how to configure this for web. So I'll narrow it down in the title too.

2

2 Answers

14
votes

Found it by inspecting the source code. So this is not in the docs, and it was a bit confusing because of all the different ways you can get a handle to the functions instance, but this is the way:

const app = firebase.app();
const functions = app.functions("europe-west2");
const callPublishVersion = functions.httpsCallable("publishVersion");
3
votes

The documentation just explains what Thijs found in the source. Extract at the time of writing:

To set regions on the client, specify the desired region at initialization:

var functions = firebase.app().functions('us-central1');

Certainly not easy to find, so an extra pointer here.