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.
To use HTTPS callable functions you must use the client SDK for your platform together with the functions.https backend API (or implement the protocol). Callables have these key difference from HTTP functions:
If you wish to specify a region for a Cloud Function that runs in any region other than us-central1, you can do this by passing the region to the FirebaseFunctions instance, using instanceFor: If you are using the local Cloud Functions emulators, then it is possible to connect to these using the useFunctionsEmulator method.
Otherwise, use the default region of us-central1 . Note also that functions connected to Firebase Hosting must be located in us-central1. The available regions for functions do not always match precisely with the regions available for your Cloud Firestore database and your Cloud Storage buckets.
To deploy only the callable, use the --only argument as shown to perform partial deploys: If you encounter permissions errors when deploying functions, make sure that the appropriate IAM roles are assigned to the user running the deployment commands.
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");
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