I'm getting the following CORS error when trying to invoke my callable function locally using the firebase cloud function emulator with my react app:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://us-central1-xxxx-xxxxx.cloudfunctions.net/getSignedUrls. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 302.
Here is my cloud function:
/functions/index.js
const functions = require('firebase-functions')
const AWS = require('aws-sdk')
const fs = require('fs')
const path = require('path')
const admin = require('firebase-admin')
admin.initializeApp()
exports.getSignedUrls = functions.https.onCall((data, context) => {
const cloudfrontAccessKeyId = "XXXXXXXXX"
let cloudfrontPrivateKey = fs.readFileSync(path.join(__dirname, 'private_key.pem'))
const signer = new AWS.CloudFront.Signer(cloudfrontAccessKeyId, cloudfrontPrivateKey)
const distName = "xxxxxxxxx.cloudfront.net"
const s3Path = data.path
let cfObjectUrl = 'https://' + distName + '/' + s3Path
const twoDays = 2*24*60*60*1000
const signedUrl = signer.getSignedUrl({
url: cfObjectUrl,
expires: Math.floor((Date.now() + twoDays)/1000)
})
return {url: signedUrl}
})
Here is where I create a reference to my apps cloud functions:
/src/firebase.js
import firebase from 'firebase/compat/app'
import { getAuth } from "firebase/auth";
import { getDatabase } from "firebase/database"
import {getFunctions} from 'firebase/functions'
const app = firebase.initializeApp({
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxx-xxxx.firebaseapp.com",
databaseURL: "https://xxx-xxxx-default-rtdb.firebaseio.com",
projectId: "xxxx-xxxx",
storageBucket: "xxxx-xxxx.appspot.com",
messagingSenderId: "xxxxxxxxxxx",
appId: "1:938967916081:web:xxxxxxxxxxxxxxxxxxx",
measurementId: "G-xxxxxxxx"
})
export const auth = getAuth(app)
export const db = getDatabase(app)
export const functions = getFunctions(app)
export default app
And here is the component in which I'm attempting to call my cloud function:
/src/components/SignedUrlTest.js
import React, { Component } from 'react';
import {httpsCallable} from 'firebase/functions'
import {functions} from '../firebase'
class SignedUrlTest extends Component {
constructor(props){
super(props)
this.state = { url: null}
this.getUrl = this.getUrl.bind(this)
}
getUrl(){
var getSignedUrls = httpsCallable(functions, 'getSignedUrls');
getSignedUrls({path: "Melissa-OShaughnessy-6-1024x683.jpg"
}).then((result) => { console.log(result.data) })
.catch((error) => {
console.log(error)
})
}
render() {
return (
<div>
<button onClick={this.getUrl}>geturl</button>
</div>
);
}
}
export default SignedUrlTest;
I've poured over the docs (https://firebase.google.com/docs/functions/callable), but can't seem to figure out why I'm unable to call my function using the client SDK. I have tested a locally emulated 'onRequest' cloud function in the same environment and was able to get an appropriate response using my web browser, but I can't figure out how to invoke an 'onCall' function from my app. Any help would be greatly appreciated :)