Vue.js + Firebase Hosting + Firebase Functions

Viewed 1206

Problem:

When a user hits refresh on my web app (a nested route like app.mycompany.com/nested/route), the route management is no longer managed by my Vue.js app (Vue Router) and instead falls back to my 404 route error handler, managed by Firebase Cloud Functions.

EDIT - See bottom, made progress

What I am trying to achieve:

  1. I'd like my "web app" written in Vue.js to work as a normal app, allow user to refresh a certain page and have it re-load that route.
  2. I would also like my api, served from app.mycompany.com/v1 to be managed by Firebase Cloud Functions and NOT my Vue.js app.
  3. I would like to keep all of this in ONE project, served by Firebase Hosting.

My Setup:

  • I am using Firebase Cloud Functions to manage my API Routes. I have a bunch of API specific routes setup in my functions/index.js file, app.get('v1/campaigns', (req, res) => {... AND app.get('v1/userInfo', (req, res) => {... etc etc.
  • I am ALSO using Firebase Hosting (With Firebase Cloud Functions) to serve up my Vue.js app.

My firebase.json file is setup like this:

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {"source": "**", "function": "app"}
    ]
  }
}
  • I am using Webpack to build out a "dist" folder for production.

What have I tried

  • I have tried multiple variations in the firebase.json rewrites section. The common approach is to set {"source": "**", "destination": "/index.html"} but then my Web App works just fine, however the API routes ".../v1/{campaigns | user}" etc don't.

  • I have tried combining {"source": "**", "destination": "/index.html"} AND {"source": "/v1**", "function": "app"} but it leads to 404 route errors still.

  • I have tried adding routes in my functions/index.js to manage this but cant seem to get it right. (I have a feeling I could get it right here, I'm just messing something up)

// My API Routes
app.get('/v1/campaigns', (req, res) => {
...some code
}

app.get('/v1/userInfo', (req, res) => {
...some code
}
    
// My Catch All Other routes and send it to Vue.js Route
app.get('**', (req, res) => {
  res.sendFile(path.join(__dirname + '/dist/index.html'))
   
exports.app = functions.https.onRequest(app)

Possible Solutions (But have a feeling there are better Options)

  1. I could seperate out my API and my Vue.js app completely into two different Firebase projects. Use Firebase Cloud Functions only for the API and then use Firebase Hosting (Technically still Firebase Cloud Functions but simpler index.js file with just one route) for the web app (Vue.js). Then update my web-app API calls to point to the new project. Problem with this is then I have two projects, two billing accounts etc etc....
  2. Investigate SSR with Vue.js and Firebase. (Not convinced this will solve the problem as I think it has something to do with the way I am setting up my app.get('/v1'... routes anyway.

Appreciate any help....

EDIT:

  • I removed a line of code in my Express.js piece that seemed to be causing part of the issue. app.use('/dist', express.static(path.join(__dirname, 'dist')))

  • I added in a router guard to vue-router that checks if the user is logged in, if they are then next() route else redirect to the login page.

I now have the API Routes and the Web App Routes at least working together in the same project and NOT returning 404 errors.

Newest Issues:

  • If I hit refresh on a route like app.mycompany.com/route1 then the app redirects to my home page and does not stay on the current page (this is most likely just a setting in my vue-router and I will post the solution here when I have it)
  • If I hit refresh on a deeply nested route like app.mycompany.com/route1/route1.1/route1.2 then the page refreshes and stays on the page without redirecting. Once again, will look into vue-router and see what I find and post the solution here.

I will update the question to answered once I solve the above.

0 Answers
Related