Vue JS 3 + Firebase: How to call Cloud Run Function (2nd gen Firebase Function) which requires authentication

  1. My app is created using Vue JS 3 and firebase is installed as a
    dependency.

  2. I created a firebase app to handle the backend. To
    handle the rest api calls from the Vue JS app I am creating a
    firebase function.

  3. The function has following dependencies in package.json:

    “dependencies”: {
    “cors”: “^2.8.5”,
    “express”: “^4.21.2”,
    “firebase-admin”: “^12.6.0”,
    “firebase-functions”: “^6.0.1”
    },

  4. The index.js in the functions folder looks like below:

const {onRequest} = require("firebase-functions/v2/https");
const {getAuth} = require("firebase-admin/auth");

const express = require("express");
const app = express();

// Add middleware to authenticate requests
app.use(async (req, res, next) => {
  const authHeader = req.headers.authorization || "";
  const token = authHeader.split("Bearer ")[1];

  if (!token) {
    return res.status(401).json({error: "Unauthorized"});
  }

  try {
    const decodedToken = await getAuth().verifyIdToken(token);
    req.user = decodedToken;
    next();
  } catch (error) {
    console.error("Error verifying token:", error);
    res.status(403).json({error: "Forbidden"});
  }
});

app.get("/hello", (req, res) => {
  res.json({message: "Hello, world!"});
});

// Expose Express API as a single Cloud Function:
exports.api = onRequest(app);

Here the function’s name is: “api”.
Now this setup works fine in local while testing.

After deploying the function the function url looks something like this: “https://REGION-MY-APP-NAME.cloudfunctions.net/api”.

Now, from the Vue JS 3 app, using axios I am trying to hit the above end point and using a firebase method to generate the token which looks like below:

    const userCredential = await signInWithEmailAndPassword(auth, emailId.value, password.value);
const token = await userCredential.user.getIdToken(); // Get the token

But this gives CORS error in the browser, (Note: I tried adding cors policy in my function code to allow all origin but it did not help)

On the other hand, in the Cloud run Function log, it says:

“The request was not authenticated. Either allow unauthenticated
invocations or set the proper Authorization header. Read more at
https://cloud.google.com/run/docs/securing/authenticating Additional
troubleshooting documentation can be found at:
https://cloud.google.com/run/docs/troubleshooting#unauthorized-client”

After getting this error, I removed below code from my index.js as well and tried. but gave the same error:

// Add middleware to authenticate requests
app.use(async (req, res, next) => {
  const authHeader = req.headers.authorization || "";
  const token = authHeader.split("Bearer ")[1];

  if (!token) {
    return res.status(401).json({error: "Unauthorized"});
  }

  try {
    const decodedToken = await getAuth().verifyIdToken(token);
    req.user = decodedToken;
    next();
  } catch (error) {
    console.error("Error verifying token:", error);
    res.status(403).json({error: "Forbidden"});
  }
});

I know, there is an option “Allow unauthenticated invocations” under the function settings. But due to some policy restriction I am unable to do so.

And I also know that there is some problem in either my token generation method in my Vue JS 3 app. I found a link to generate the token in node js (https://cloud.google.com/docs/authentication/get-id-token#node.js)

My problem is I only have a Vue JS 3 app in front-end and I want to use this 2nd gen function as my backend with express js to do backend related tasks like storing and retrieving data from Cloud FireStore and related things… But stuck at this authentication error. Need to help resolving this 403 auth error.

If any other information is needed. Please let me know, I will provide.