Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular 19 SSR with Firebase hosting or Firebase App Hosting Fail #29488

Closed
hittten opened this issue Jan 26, 2025 · 3 comments · Fixed by #29599
Closed

Angular 19 SSR with Firebase hosting or Firebase App Hosting Fail #29488

hittten opened this issue Jan 26, 2025 · 3 comments · Fixed by #29599
Assignees
Labels
area: @schematics/angular freq1: low Only reported by a handful of users who observe it rarely severity3: broken type: bug/fix

Comments

@hittten
Copy link

hittten commented Jan 26, 2025

Which @angular/* package(s) are the source of the bug?

core, platform-server

Is this a regression?

Yes

Description

Angular 19 setup with SSR fails when trying to deploy it with firebase hosting or app hosting.

I've created a very basic angular:
ng new angular19ssr
✔ Which stylesheet format would you like to use? Sass (SCSS) [ https://sass-lang.com/documentation/syntax#scss ]
✔ Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? Yes
✔ Would you like to use the Server Routing and App Engine APIs (Developer Preview) for this server application? No
CREATE angular19ssr/README.md (1475 bytes)
CREATE angular19ssr/.editorconfig (314 bytes)
CREATE angular19ssr/.gitignore (587 bytes)
CREATE angular19ssr/angular.json (2938 bytes)
CREATE angular19ssr/package.json (1281 bytes)
CREATE angular19ssr/tsconfig.json (915 bytes)
CREATE angular19ssr/tsconfig.app.json (489 bytes)
CREATE angular19ssr/tsconfig.spec.json (434 bytes)
CREATE angular19ssr/.vscode/extensions.json (130 bytes)
CREATE angular19ssr/.vscode/launch.json (470 bytes)
CREATE angular19ssr/.vscode/tasks.json (938 bytes)
CREATE angular19ssr/src/main.ts (250 bytes)
CREATE angular19ssr/src/index.html (298 bytes)
CREATE angular19ssr/src/styles.scss (80 bytes)
CREATE angular19ssr/src/main.server.ts (264 bytes)
CREATE angular19ssr/src/server.ts (1764 bytes)
CREATE angular19ssr/src/app/app.component.scss (0 bytes)
CREATE angular19ssr/src/app/app.component.html (19903 bytes)
CREATE angular19ssr/src/app/app.component.spec.ts (934 bytes)
CREATE angular19ssr/src/app/app.component.ts (289 bytes)
CREATE angular19ssr/src/app/app.config.ts (438 bytes)
CREATE angular19ssr/src/app/app.routes.ts (77 bytes)
CREATE angular19ssr/src/app/app.config.server.ts (351 bytes)
CREATE angular19ssr/public/favicon.ico (15086 bytes)
✔ Packages installed successfully.
Successfully initialized git.

Afterwards, I changed the configuration of the angular.json:
https://github.com/hittten/angular19ssr/blob/main/angular.json

"prerender": {
              "discoverRoutes": false,
              "routesFile": "src/prerender.routes.txt"
            },

https://github.com/hittten/angular19ssr/blob/main/src/prerender.routes.txt

src/prerender.routes.txt
/pre-render

This means that only the pre-render route should be pre-rendered and the rest should be SSR.

https://github.com/hittten/angular19ssr/blob/main/src/app/app.routes.ts

export const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    redirectTo: 'home'
  },
  {
    path: 'home',
    loadComponent: () => import('./home-page.component').then(m => m.HomePageComponent)
  },
  {
    path: 'ssr',
    loadComponent: () => import('./ssr-page.component').then(m => m.SsrPageComponent)
  },
  {
    path: 'pre-render',
    loadComponent: () => import('./pre-render-page.component').then(m => m.PreRenderPageComponent)
  },
  {
    path: '**',
    loadComponent: () => import('./not-found-page.component').then(m => m.NotFoundPageComponent)
  }
];

And when you try to load any route with SSR you get this error: Service Unavailable

You can see this in: https://twistseed-poc.web.app/ssr
The only route that works is https://twistseed-poc.web.app/pre-render but it takes a long time and the root https://twistseed-poc.web.app
also a route like https://twistseed-poc.web.app/does-not-exist but return: "Internal Server Error"

Please provide a link to a minimal reproduction of the bug

https://github.com/hittten/angular19ssr

Please provide the exception or error you saw

The deployment works, i.e. the app deploys without any problem, but then it doesn't work as it should. Error messages are seen in the logs:

INFO 2025-01-26T15:01:32.227333Z Default STARTUP TCP probe succeeded after 1 attempt for container "worker" on port 8080.
DEFAULT 2025-01-26T15:01:32.438634Z Unhandled rejection
ERROR 2025-01-26T15:01:32.439053Z TypeError: app is not a function at /workspace/bootstrap.js:10:19
WARNING 2025-01-26T15:01:32.703852737Z Container called exit(16).
ERROR 2025-01-26T15:01:32.704115Z Error: Process exited with code 16 at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:96:22) at process.emit (node:events:518:28) at process.emit (node:domain:489:12) at process.exit (node:internal/process/per_thread:185:15) at sendCrashResponse (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/logger.js:49:9) at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:89:44) at process.emit (node:events:518:28) at process.emit (node:domain:489:12) at emitUnhandledRejection (node:internal/process/promises:250:13) at throwUnhandledRejectionsMode (node:internal/process/promises:385:19)
  {
    "textPayload": "Error: Process exited with code 16\n    at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:96:22)\n    at process.emit (node:events:518:28)\n    at process.emit (node:domain:489:12)\n    at process.exit (node:internal/process/per_thread:185:15)\n    at sendCrashResponse (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/logger.js:49:9)\n    at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:89:44)\n    at process.emit (node:events:518:28)\n    at process.emit (node:domain:489:12)\n    at emitUnhandledRejection (node:internal/process/promises:250:13)\n    at throwUnhandledRejectionsMode (node:internal/process/promises:385:19)",

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 19.1.4
Node: 20.18.1
Package Manager: npm 11.0.0
OS: darwin arm64

Angular: 19.1.3
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1901.4
@angular-devkit/build-angular   19.1.4
@angular-devkit/core            19.1.4
@angular-devkit/schematics      19.1.4
@angular/cli                    19.1.4
@angular/fire                   19.0.0
@angular/ssr                    19.1.4
@schematics/angular             19.1.4
rxjs                            7.8.1
typescript                      5.7.3
zone.js                         0.15.0

firebase --version
13.29.2

Anything else?

No response

Update

The best workaround, see this commit: hittten/angular19ssr@e22339c

@JeanMeche JeanMeche transferred this issue from angular/angular Jan 26, 2025
@alan-agius4 alan-agius4 added type: bug/fix freq1: low Only reported by a handful of users who observe it rarely severity3: broken area: @schematics/angular labels Jan 26, 2025
@alan-agius4 alan-agius4 self-assigned this Jan 26, 2025
@alan-agius4
Copy link
Collaborator

As the error suggests app hosting is expecting an app function to be exported You re-name the app const to expressApp and add the following;

export const app = () => expressApp;

@hittten
Copy link
Author

hittten commented Jan 31, 2025

@alan-agius4 Thanks for the recommendation, I actually have a workaround by changing the server.ts file of Angular and adapting it the old way in version 18 and I got it working. You can see the commit: hittten/angular19ssr@fbb9090

but the best workaround that I found reading the documentation: https://angular.dev/guide/hybrid-rendering#configuring-a-nodejs-server and changing it a little bit was this: hittten/angular19ssr@e22339c

I had also opened the same issue in the firebase-tools repository: firebase/firebase-tools#8141 and I found this on firebase-tools side: firebase/firebase-tools#8145

Additionally, I have tried to get REQUEST and RESPONSE_INIT to work (https://angular.dev/guide/hybrid-rendering#accessing-request-and-response-via-di) and there is no way to get it to work.

import {Component, RESPONSE_INIT, REQUEST, inject} from '@angular/core';

@Component({
  selector: 'app-not-found-page',
  imports: [],
  template: `
    <h1>404 Not Found</h1>
  `,
  styles: ``
})
export class NotFoundPageComponent {
  private response = inject(RESPONSE_INIT)
  private request = inject(REQUEST)

  constructor() {
    if (this.response !== null) {
      this.response.status = 404
    }

    if (this.request !== null) {
      console.log(this.request.url)
    }

    console.log("request", this.request)
    console.log("response", this.response)
  }
}
  1. I can not see a 404 status response
  2. I can not see any resquest info like url

In both cases request and response are undefined on the server side.

2025-01-31T20:53:40.709416Z request null
2025-01-31T20:53:40.709727Z response null

@alan-agius4
Copy link
Collaborator

The tokens will not work with the CommonEngine, to function properly the API described in https://angular.dev/guide/hybrid-rendering needs to be used.

alan-agius4 added a commit to alan-agius4/angular-cli that referenced this issue Feb 10, 2025
This update is required for Firebase functions compatibility.

Closes angular#29488
alan-agius4 added a commit that referenced this issue Feb 10, 2025
This update is required for Firebase functions compatibility.

Closes #29488

(cherry picked from commit aa0ae45)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: @schematics/angular freq1: low Only reported by a handful of users who observe it rarely severity3: broken type: bug/fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants