#Angular SSR - Firebase cloud function deployment

46 messages · Page 1 of 1 (latest)

safe veldt
#

Hi there,

I am stuck with cloud function deployment at the moment and wondering if anyone could help answer to some of my question

  • After I use "$ng add @angular/firebase" do I need to use "$firebase init" ?
    This is because after I ran command "$ng add @angular/firebase" I cannot see cloud "Functions" folder in my directory.

  • Do I still need to write a function in "functions/src/index.ts to point to dist/project/server/main.js?

Thank you

safe veldt
#

😢 no one reply at all.

hollow rover
#

After that, you must config your app to use it by using @angular/fire command as pointed out at https://github.com/angular/angularfire/blob/master/docs/install-and-setup.md

This should display a prompt to select your firebase project, then select the services you want to add and after that it will fetch the environment variables and configure your app.

You should end up with something like this (Nx workspace + Angular 17 in my case) at the src/app/app.config.ts file:

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { appRoutes } from './app.routes';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, provideAuth } from '@angular/fire/auth';
import {
  getAnalytics,
  provideAnalytics,
  ScreenTrackingService,
  UserTrackingService,
} from '@angular/fire/analytics';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { getFunctions, provideFunctions } from '@angular/fire/functions';
import { getMessaging, provideMessaging } from '@angular/fire/messaging';
import { getStorage, provideStorage } from '@angular/fire/storage';

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(appRoutes)],
  providers: [
    provideRouter(appRoutes),
    provideFirebaseApp(() =>
      initializeApp({
        projectId: 'your-project-id-from-firebase',
        // ... All other fields automatically filled
      })
    ),
    provideAuth(() => getAuth()),
    provideAnalytics(() => getAnalytics()),
    ScreenTrackingService,
    UserTrackingService,
    provideFirestore(() => getFirestore()),
    provideFunctions(() => getFunctions()),
    provideMessaging(() => getMessaging()),
    provideStorage(() => getStorage()),
  ],
};
#

I used to rely on https://github.com/simondotm/nx-firebase until some unknown bug hit me but this should also help you in case you want to try NX Workspace to split and organize both your app and your CFs in one monorepo 🙂

Planning to implement it tomorrow in my local project as I have begun starting from scratch to stay up to date with the latest Angularfire (v7 onwards) and Angular 17-18 😳

GitHub

Firebase plugin for Nx Monorepos. Contribute to simondotm/nx-firebase development by creating an account on GitHub.

fallen raptor
#

@hollow rover I am trying to implement SSR in my Angular 17/Firebase application but am still stumbling over errors. I read some articles about using ng add @angular/fire, but I am still facing some problems. I tried updating my angular.json, but I am confused about whether I need Angular Universal or Angular SSR since some guides had different explanations. I also tried app hosting, but it didn't work for me either.

Would it be possible to pay you to jump on a 15-minute screensharing call on Discord so you can show me how it's done?

primal marsh
fallen raptor
# primal marsh Angular Universal is old stuff. Use Angular SSR. See https://github.com/angular/...

Thanks for the link! Ok then that is good to know that it is deprecated. I tried to follow the manual. I deployed via ng deploy but the page is not using ssr it seems. In my dist folder I am also not seeing the server build. So I guess something wrong in my angular.json`?

"deploy": {
"builder": "@angular/fire:deploy",
"options": {
"version": 2
},
"configurations": {
"production": {
"buildTarget": "artlistingpro:build:production",
"serveTarget": "artlistingpro:serve:production"
},
"development": {
"buildTarget": "artlistingpro:build:development",
"serveTarget": "artlistingpro:serve:development"
}
},
"defaultConfiguration": "production"
},

fallen raptor
#

Now I have added:
"deploy": {
"builder": "@angular/fire:deploy",
"options": {
"version": 2,
"ssr": true
},

and it changed the built process but I get this:
./node_modules/canvas/build/Release/canvas.node:1:2 - Error: Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

🙃 🙃 🙃

If anybody has experienced similar stuff please post it here. Otherwise I will continue debugging and keep this chat as history for others.

#

I also get this error:
NullInjectorError: NullInjectorError: No provider for InjectionToken angularfire2.app.options!

since I removed this:
importProvidersFrom(AngularFireModule.initializeApp(environment.firebase))

but I would have thought I would use:
return initializeApp(environment.firebase);

Instead anyways

fallen raptor
#

when I migrate does it mean I cant use angular fire at all?

imports like this i mean?
import {
AngularFirestore,
AngularFirestoreDocument,
} from "@angular/fire/compat/firestore";

#

I will paypal anyone who can hop on a call and solve this with me 50€ xD

primal marsh
#

do not use anything from the compat package. Follow the official angularfire documentation.

fallen raptor
fallen raptor
primal marsh
#

logEvent is a function, that takes Analytics as a parameter. Not a method of Analytics.

fallen raptor
fallen raptor
#

well , removed all the compat stuff but still:
<app-root></app-root>

fallen raptor
#

sorry I am just really exhausted from trying to get this to work.
As far as I understood the app-root should be populated with the rendered content. So when I check "view page source" it should show the rendered page, but it doesnt show the rendered page. I think I am just using some wrong command or have some wrong angular.json setup which causes the app to not be deployed via SSR.

primal marsh
fallen raptor
#

hm alright, then I have to update the angular version. I will try tomorrow again then 🙂

hollow rover
fallen raptor
fallen raptor
#

I mean at least the version update worked xD

fallen raptor
#

I checked out an ssr repo example and made the following changes:
Changed
"builder": "@angular-devkit/build-angular:browser"
to
"builder": "@angular-devkit/build-angular:application"

and added the following:
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"server": "src/main.server.ts",
"prerender": true,
"ssr": {
"entry": "server.ts"
},

#

Now I only got this error left i think:
X [ERROR] No loader is configured for ".node" files: node_modules/canvas/build/Release/canvas.node

node_modules/canvas/lib/bindings.js:3:25:
  3 │ const bindings = require('../build/Release/canvas.node')
#

the previous error was solved by adding :
"externalDependencies": [
"canvas"
]

to the
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {

#

Now next error is:
window is not defined
at eval (i:/I-Dokumente/ArtListingPro/codebase/services/ArtListingPro-Frontend/src/app/services/google-drive.service.ts:42:19)
at async instantiateModule (file:///I:/I-Dokumente/ArtListingPro/codebase/services/ArtListingPro-Frontend/node_modules/vite/dist/node/chunks/dep-k5wXcrSr.js:54897:9
Click outside, press Esc key, or fix the code to dismiss.

fallen raptor
#

After more fiddling around I got it to work! BUT it just works for ng serve but when I do ng build it somehow gets stuck for infinity.... so i guess more debugging

safe veldt
#

omg guys! sorry I only see the message just now. Thank you so much for all your reply. 🥲

safe veldt
safe veldt
#

Hi guys,
Here is what I understand so far and I am struggling to understand the at the deployment step.
Though I actually manage to deploy it firebase and it works but I don't understand how it works. I really appreciate if you could explain this to me.

Thank you in advance!

adding Angular SSR to Angular project

$ng add @angular/ssr

package.json

Check the command

"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "dev:ssr": "ng run saoakev3:serve-ssr",
    "serve:ssr": "node dist/saoakev3/server/main.js",
    "build:ssr": "ng build && ng run saoakev3:server",
    "prerender": "ng run saoakev3:prerender"
 },

Run server to check if SSR is working properly

$npm run dev:ssr

Angular generate two bundles in dist folder

dist/broswer
dist/server

HTML payload is visible at <app-root>..

Understanding how it works

commonEngine is the Angular server side engine that use server bundle that is available in dist/server to produce HTML payload

When HTTP request (based on the URL) hit, CommonEngine in Server.ts get trigger and using the information available in server bundle and application get render

#

Deployment to Firebase

$firebase init

function
hosting

Here is where I am struggling to understand

  • What I understand so far is that, I install hosting for the angular static file bundle (dist/browser)
  • Install function to run function for the server bundle

What get me confused is that how to link firebase function to dist/server?
What is the write configure in firebase.json?

{
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log",
        "*.local"
      ],
      "predeploy": [
        "npm --prefix \"$RESOURCE_DIR\" run build"
      ]
    }
  ],
  "hosting": {
    "source": ".",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "frameworksBackend": {
      "region": "europe-west1"
    }
  }
}
hollow rover