Search code examples
firebasegoogle-cloud-functionsfirebase-hostingfirebase-cli

Best setup/workflow for testing and deploying an application using Google Firebase Hosting and Functions


I built a small web application (www.suntax.de) with vuejs and hosted on Google Firebase. I use the Firebase Hosting, Database and Functions. I use Functions to do some calculation on the backend.

Everything is running now, but I had some trouble getting there and some things I would like to improve regarding my workflow. Thus, I would like to explain you what I did and where I struggle now.

First I set up the vuejs applicationd deployed it to firebase. I added my custom domain and everything was doing fine. Later I implemented the cloud function and want to make a call from my vuejs app. After firebase deploy, I can call this function in the browser and it just works fine: https://us-central1-suntax-6d0ea.cloudfunctions.net/calcEEGcompensation?year=2013&month=1&size=10

Now I thought, that I just call the URL of the function from my vuejs app. But then I got the following error message: [Error] Origin * is not allowed by Access-Control-Allow-Origin.

I was then reading that I had to add a rewritesection in the firebase.json:

Now my firebase.json looks like this:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    // Add the following rewrites section *within* "hosting"
   "rewrites": [ {
      "source": "/calcEEGcompensation", "function": "calcEEGcompensation"
    } ]
  }
}

Now I was able to call my firebase function with the following URL: https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10

After integrating the above URL in my vuejs application, the application is running fine after deployment to firebase server.

As I want to keep improving the application, I would like to test everything locally before deploying.

I know that I can run firebase hosting and functions locally by: firebase serve --only functions,hosting

However, now my application has the hard coded call to my function https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10 and this again leads to the error [Error] Origin * is not allowed by Access-Control-Allow-Origin.

But also changing the URL to the local function http://localhost:5001/suntax-6d0ea/us-central1/calcEEGcompensation?year=2013&month=1&size=10 leads to the error message [Error] Origin * is not allowed by Access-Control-Allow-Origin.

Some further reading brought me to the solution with cors. So I changed my function to:

const functions = require('firebase-functions');
const cors = require('cors')({origin: true});

exports.calcEEGcompensation = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        const yearOfCommissioning = req.query.year;
        const monthOfCommissioning = req.query.month;
        const pvsystemsize = req.query.size;

        ...

        res.send("hello");
    });
});

This helped and everything works now: - The deployed application is still running fine. - I can run the application locally while calling the local function as well as the deployed function. I just have to change the URL of the function.

But this is now my question: Can I solve this issue in a better way? If I test the vuejs application and the function locally, I have to change the function URL before deployment. And then I have to change it back while testing locally. I was not able to test my application and function locally without cors.

My ideal solution would be to have a setup, that can be fully tested locally and which can be easily deployed with firebase deploy without any changes of URLs. Is this possible?

Thanks and best regards, Christoph


Solution

  • I found the solution which is pretty simple and does exactly what I want. I have no idea why I did not figure it out before. Here is what I did:

    I just call the relative URL from my firebase hosting:

    calcEEGcompensation?year=2013&month=1&size=10

    and everything works fine if the rewrites are properly set in firebase.json:

    {
      "database": {
        "rules": "database.rules.json"
      },
      "hosting": {
        "public": "public",
        "ignore": [
          "firebase.json",
          "**/.*",
          "**/node_modules/**"
        ],
        // Add the following rewrites section *within* "hosting"
       "rewrites": [ {
          "source": "/calcEEGcompensation", "function": "calcEEGcompensation"
        } ]
      }
    }
    

    After setting up everything like this, I can just execute firebase serve --only functions,hosting and I can test everything locally. After executing firebase deploy, everything runs smoothly on the server.

    I do not need cors.

    Thanks @wonsuc for your answers.