The following is the client-side code to call the cloud function:
// add a new post
addPostForm.addEventListener('click', (e) => {
e.preventDefault();
const addPost = httpsCallable(functions, 'addPost');
addPost({
title: addPostForm.postTitle.value,
description: addPostForm.postDescription.value,
})
.then(() => {
addPostForm.reset(),
addPostModal.classList.remove('open');
addPostForm.querySelector('.error').textContent = '';
})
.catch(error => {
addPostForm.querySelector('.error').textContent = error.message;
})
});
The cloud function:
exports.addPost = functions.https.onCall((data, context) => {
if(!context.auth){
throw new functions.https.HttpsError(
'unauthenticated',
'only authenticated users can post'
);
}
if(data.text.length > 140){
throw new functions.https.HttpsError(
'invalid-argument',
'description must be no more than 140 characters long'
);
}
return admin.firestore().collection('Posts').add({
title: data.title,
description: data.description,
likes: '',
bookmarks: '',
});
});
Firebase Setup:
import { initializeApp, getApp } from "firebase/app";
import { getAuth, connectAuthEmulator } from "firebase/auth";
import { getStorage, connectStorageEmulator } from "firebase/storage";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
import { getFunctions, connectFunctionsEmulator } from "firebase/functions";
const firebaseConfig = {
"config"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const storage = getStorage(app);
const functions = getFunctions(getApp(), app);
if (window.location.hostname.includes("localhost")) {
connectAuthEmulator(auth, "http://localhost:9099");
connectFirestoreEmulator(db, 'localhost', 8080);
connectStorageEmulator(storage, 'localhost', 9199);
connectFunctionsEmulator(functions, "localhost", 5001);
}
export { auth, db, storage, functions };
Error
Access to fetch at ‘http://localhost:5001/app/object/addPost’
From origin ‘http://localhost:5173’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: 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.
What’s the problem here? Will I need to set up firebase admin to grant access rights, and if I turn CORS off in the browser will that present a security issue on production?
2
Answers
After over a week of learning and trying to find the right solution for this problem, I came across a video from one of my favorite YT creators Web Dev Simplified.
Here he elegantly explains the CORS error and provides a simple yet effective solution. Installing the Express and CORS library through NPM within my cloud functions folder and requiring them both in the index.js file. Writing a function that allows you to change the access origin should be enough to solve this error.
Changing the origin to "*" allows the access request origin to be from any source. You can also change this to a specific URL if you needed.
CORS error occurs when the request from a certain origin (eg. abc.com) is restricted to access resources on another origin (eg. xyz.com). This is a security measure enforced at the browser level and this is not related to Firebase setup.
There are two ways through which this can be solved,
Disable CORS in the browser. This is NOT recommended and should not be done for most cases.
If you are in control of the server, then you can modify your application to receive requests from a certain source.
In this case, you are in control of both the server and the client.
you just have to configure the server application (Cloud Functions in this case) to accept requests from the client.
For this, in the CF code, you can set the header
Access-Control-Allow-Origin
to the value of the client origin (Eg. localhost:PORT_NUM) or simply set the value to*
to receive requests from all client origins.As mentioned in the Answer, you can follow the checklist for the firebase callable functions cors errors :
you can refer to the Documentation which explains about how to connect your app to cloud function emulator.
For more information , you can refer to the Answer and git issue.