Martin Erlic
Martin Erlic

Reputation: 5667

CORS Issue with Firebase Cloud Function Despite CORS Middleware

I'm facing an issue with CORS when deploying my Firebase Cloud Function. I have set up the CORS middleware, but I'm still getting a CORS error when trying to make a request to the function. Here is the code for my Cloud Function:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import cors from 'cors';

admin.initializeApp();

// Initialize cors middleware
const corsHandler = cors({ origin: true });

export const getSecretData = functions.https.onRequest((request, response) => {
  // Run the cors middleware
  corsHandler(request, response, async (err: Error | null) => {
    if(err) {
      response.status(500).send('CORS failed: ' + err.message);
      return;
    }

    // Verify the user's token
    if (!request.headers.authorization || !request.headers.authorization.startsWith('Bearer ')) {
      response.status(403).send('Unauthorized');
      return;
    }

    let idToken: string;
    if (request.headers.authorization && request.headers.authorization.startsWith('Bearer ')) {
      idToken = request.headers.authorization.split('Bearer ')[1];
    } else {
      response.status(403).send('Unauthorized');
      return;
    }

    try {
      const decodedIdToken = await admin.auth().verifyIdToken(idToken);
      console.log('ID Token correctly decoded', decodedIdToken);
    } catch (error) {
      console.error('Error while verifying Firebase ID token:', error);
      response.status(403).send('Unauthorized');
      return;
    }

    // Fetch secret data
    const secretData = {
      key: "value",
      anotherKey: "my secret",

Despite having the CORS middleware set up and running it for each request, I'm still getting a CORS error. The error persists even after I added error handling to the CORS middleware to respond with a detailed error message if CORS handling fails:

OPTIONS
https://us-central1-firebase-elgami.cloudfunctions.net/ext-moralis-auth-requestMessage
CORS Missing Allow Origin

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://us-central1-firebase-elgami.cloudfunctions.net/ext-moralis-auth-requestMessage. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 404.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://us-central1-firebase-elgami.cloudfunctions.net/ext-moralis-auth-requestMessage. (Reason: CORS request did not succeed). Status code: (null).

Here is my app code:

import React, { useState, useEffect } from 'react';
import { signInWithMoralis as signInWithMoralisByEvm } from '@moralisweb3/client-firebase-evm-auth';
import { signInWithMoralis as signInWithMoralisBySolana } from '@moralisweb3/client-firebase-sol-auth';
import { httpsCallable } from 'firebase/functions';
import { User } from 'firebase/auth';
import { auth, functions, moralisAuth } from '../firebase'; // Make sure the path to your firebase config file is correct
import WalletConnectProvider from '@walletconnect/web3-provider';
import { Web3Provider } from '@ethersproject/providers';

function Login() {
  const [currentUser, setCurrentUser] = useState(null);

  useEffect(() => {
    console.log("Firebase User: ", auth.currentUser);
    setCurrentUser(auth.currentUser);
  }, []);

  async function signInWithMetamask() {
    try {
      const result = await signInWithMoralisByEvm(moralisAuth);
      console.log("Moralis User: ", result.credentials.user);
      setCurrentUser(result.credentials.user);
    } catch (error) {
      console.log('Error signing in with MetaMask:', error);
    }
  }

  async function signInWithWalletConnect() {
    localStorage.removeItem('walletconnect');

    const provider = new WalletConnectProvider({
      rpc: {
        1: 'https://mainnet.infura.io/v3/ef3da53f237c4a2e83f7905f6f159584',
      },
    });

    await provider.enable();

    const result = await signInWithMoralisByEvm(moralisAuth, {
      provider: new Web3Provider(provider),
    });

    setCurrentUser(result.credentials.user);
  }

  async function signInWithPhantom() {
    const result = await signInWithMoralisBySolana(moralisAuth);
    setCurrentUser(result.credentials.user);
  }

  async function signOut() {
    await auth.signOut();
    setCurrentUser(null);
  }

  async function getSecretData() {
    try {
      // Ensure there is a currently signed-in user
      if (!auth.currentUser) {
        throw new Error('No user currently signed in');
      }

      // Get the ID token of the currently signed-in user
      const idToken = await auth.currentUser.getIdToken();

      // Make an authenticated HTTP request to the getSecretData function
      const response = await fetch('https://us-central1-firebase-elgami.cloudfunctions.net/getSecretData', {
        headers: {
          'Authorization': `Bearer ${idToken}`
        }
      });

      if (!response.ok) {
        throw new Error('HTTP error ' + response.status);
      }

      const data = await response.json();
      alert(JSON.stringify(data));
    } catch (e) {
      console.log('Error getting secret data:', e);
      alert(e.message);
    }
  }

  return (
    <div className="App">
      <h1>🔒 Authenticate with Moralis Web3</h1>

      <p>
        Current user:&nbsp;
        <strong>
          {currentUser ? (
            <>
              address: {currentUser.displayName}, uid: {currentUser.uid}
            </>
          ) : (
            'unknown'
          )}
        </strong>
      </p>

      <h4>Authentication</h4><br /><br />

      <button onClick={signInWithMetamask}>Sign in with MetaMask</button><br /><br />

      <button onClick={signInWithWalletConnect}>Sign in with WalletConnect</button><br /><br />

      <button onClick={signInWithPhantom}>Sign in with Phantom</button><br /><br />

      <button onClick={signOut}>Sign out</button><br /><br />

      <button onClick={getSecretData}>Get secret data</button>
    </div>
  );
}

export default Login;

Is there something I'm missing in my setup or implementation?

Upvotes: -1

Views: 500

Answers (1)

Martin Erlic
Martin Erlic

Reputation: 5667

If you encounter this problem, it might seem like a CORS issue, but it's actually due to the Moralis authentication extension not being configured in Firebase. This setup isn't evident in the sample app or written documentation. However, a clearer guide can be found in this video tutorial: https://moralis.io/create-a-web3-firebase-login-with-metamask/

Upvotes: -1

Related Questions