Search code examples
firebasesingle-page-applicationgoogle-cloud-functionsvue-routerfirebase-hosting

Vue.js SPA on Firebase Hosting with wildcard rewrite to Firebase Cloud Functions


I have a vue.js app using vue-router. If I serve the app in the default public directory using firebase hosting and try to use https functions, the function does not get called because the router picks up the path and tries to render a route.

I moved the app to public/app and altered the firebase.json rewrites accordingly (my app content is working as expected by visiting URLs ending in /app/**) but I still cannot get the functions to run.

I tried using a rewrite with wildcard as follows

"rewrites": [
  {
    "source": "/:function",
    "function": ":function"
  },
  {
    "source": "/app/**",
    "destination": "/app/index.html"
  }
]

but this doesn't work either (I'm not sure if it's meant to with functions, I can't find an example anywhere).

e.g. I have used the default functions index.js (and uncommented the helloWorld function) and so expect /helloWorld to output the response from the helloWorld function (as I said before, if I navigate to /app/route, I get the output I expect from my vue application).

Should this work? Or do I need to do something completely different?

------Edit

After Doug's comment, I updated my functions script to the following

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

const app = express();

app.get("/:function", (req, res) => {
    switch(req.params.function) {

        case 
            "helloWorld" : helloWorld(res)
            break;

        default : res.send("Invalid function requested.")

    }
});

function helloWorld(res) {
    res.send("Hello world!");
}

exports.api = functions.https.onRequest(app);

This works as expected when serving only functions.

But when I run firebase serve, the rewrites (as follows) are still not working for the api routes I expect to rewrite to my functions:

    "rewrites": [
      {
        "source": "/api/**",
        "function": "api"
      },
      {
        "source": "/app/**",
        "destination": "/app/index.html"
      }
    ]

I'm suspicious that when running firebase serve, it is not actually serving the functions since I don't get any endpoints listed in the terminal.


Solution

  • I got everything working as expected with the following as an example:

    functions/src/index.ts

    import * as functions from 'firebase-functions';
    import * as express from 'express';
    
    const app = express();
    
    app.get("/:function", (req, res) => {
        switch(req.params.function) {
    
            case 
                "helloWorld" : helloWorld(res)
                break;
    
            default : res.send("Invalid function requested.")
    
        }
    });
    
    app.get("/users/:id", (req, res) => {
        res.send("User with ID: " + req.params.id)
    });
    
    function helloWorld(res) {
        res.send("Hello world!");
    }
    
    exports.api = functions.https.onRequest(app);

    firebase.json (redirects and rewrites)

        "redirects": [
          {
            "source": "/",
            "destination": "/app/",
            "type": 301
          }
        ],
        "rewrites": [
          {
            "source": "/app/**",
            "destination": "/app/index.html"
          },
          {
            "source": "/**",
            "function": "api"
          }
        ]