Skip to content

Commit 0fe25e3

Browse files
Merge origin/main into fix/ng-add-empty-features-warning
Resolve the src/schematics/setup/index.ts import conflict: keep main's new firebaseConfigs import and add featuresPromptMessage to the prompts import. No logic change from either side.
2 parents 3f32bb9 + b551b5f commit 0fe25e3

34 files changed

Lines changed: 3255 additions & 91 deletions

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ jobs:
168168
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
169169
with:
170170
node-version: '20'
171-
registry-url: 'https://registry.npmjs.org'
171+
registry-url: 'https://wombat-dressing-room.appspot.com/'
172172
check-latest: false
173173
- name: 'Download Artifacts'
174174
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,16 @@ export class AppComponent {
6666

6767
[Quickstart](docs/install-and-setup.md) - Get your first application up and running by following our quickstart guide.
6868

69+
[Deploying SSR to App Hosting](docs/app-hosting.md) - Deploy a server-rendered app to Firebase App Hosting, and avoid the silent SSR-to-CSR fallback.
70+
6971
[Contributing](CONTRIBUTING.md)
7072

7173
[Stackblitz Template](https://stackblitz.com/edit/angular-fire-start) - Remember to set your Firebase configuration in `app/app.module.ts`.
7274

7375
[Upgrading from v6.0? Check out our guide.](docs/version-7-upgrade.md)
7476

77+
[Upgrading from AngularFire 20? See the v21 upgrade guide.](docs/version-21-upgrade.md)
78+
7579
### Sample app
7680

7781
The [`sample`](sample) folder contains a kitchen sink application that demonstrates use of the "modular" API, in a zoneless server-rendered application, with all the bells and whistles.
@@ -142,43 +146,49 @@ import { } from '@angular/fire/storage';
142146
<tr>
143147
<td>
144148

149+
#### [Data Connect](docs/data-connect.md#data-connect)
150+
```ts
151+
import { } from '@angular/fire/data-connect';
152+
```
153+
</td>
154+
<td>
155+
145156
#### [Performance Monitoring](docs/performance.md#performance-monitoring)
146157
```ts
147158
import { } from '@angular/fire/performance';
148159
```
149160
</td>
161+
</tr>
162+
<tr>
150163
<td>
151164

152165
#### [Realtime Database](docs/database.md#realtime-database)
153166
```ts
154167
import { } from '@angular/fire/database';
155168
```
156169
</td>
157-
</tr>
158-
<tr>
159170
<td>
160171

161172
#### [Remote Config](docs/remote-config.md#remote-config)
162173
```ts
163174
import { } from '@angular/fire/remote-config';
164175
```
165176
</td>
177+
</tr>
178+
<tr>
166179
<td>
167180

168181
#### [App Check](docs/app-check.md#app-check)
169182
```ts
170183
import { } from '@angular/fire/app-check';
171184
```
172185
</td>
173-
</tr>
174-
<tr>
175186
<td>
176187

177-
#### [Vertex AI](docs/vertexai.md#vertex-ai)
188+
#### [AI Logic](docs/ai.md#ai-logic)
178189
```ts
179-
import { } from '@angular/fire/vertexai';
190+
import { } from '@angular/fire/ai';
180191
```
181192
</td>
182-
183193
</tr>
184194
</table>

docs/ai.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<small>
2+
<a href="https://github.com/angular/angularfire">AngularFire</a> &#10097; <a href="../README.md#developer-guide">Developer Guide</a> &#10097; AI Logic
3+
</small>
4+
5+
# AI Logic
6+
7+
Firebase AI Logic gives you access to the latest generative AI models from Google: the Gemini models and Imagen models.
8+
9+
[Learn more](https://firebase.google.com/docs/ai-logic)
10+
11+
> Firebase AI Logic was previously called **Vertex AI in Firebase**. If you are upgrading from AngularFire 20, the module moved from `@angular/fire/vertexai` to `@angular/fire/ai` and most symbols were renamed (`provideVertexAI` to `provideAI`, `VertexAI` to `AI`). One is not a rename: plain `getAI()` uses the Gemini Developer API backend, so the old `getVertexAI()` maps to `getAI(app, { backend: new VertexAIBackend() })`. Running `ng update @angular/fire` rewrites all of this for you and keeps your app on the Vertex AI backend. See the [AngularFire 20 to 21 upgrade guide](./version-21-upgrade.md).
12+
13+
## Dependency Injection
14+
15+
As a prerequisite, ensure that `AngularFire` has been added to your project via
16+
```bash
17+
ng add @angular/fire
18+
```
19+
20+
Provide an AI instance in the application's `app.config.ts`:
21+
22+
```ts
23+
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
24+
import { provideAI, getAI } from '@angular/fire/ai';
25+
26+
export const appConfig: ApplicationConfig = {
27+
providers: [
28+
provideFirebaseApp(() => initializeApp({ ... })),
29+
provideAI(() => getAI()),
30+
...
31+
],
32+
...,
33+
}
34+
```
35+
36+
Next inject `AI` into your component:
37+
38+
```typescript
39+
import { Component, inject } from '@angular/core';
40+
import { AI } from '@angular/fire/ai';
41+
42+
@Component({ ... })
43+
export class MyComponent {
44+
private ai = inject(AI);
45+
...
46+
}
47+
```
48+
49+
## Firebase API
50+
51+
AngularFire wraps the Firebase JS SDK to ensure proper functionality in Angular, while providing the same API.
52+
53+
Update the imports from `import { ... } from 'firebase/ai'` to `import { ... } from '@angular/fire/ai'` and follow the official documentation.
54+
55+
[Getting Started](https://firebase.google.com/docs/ai-logic/get-started?platform=web) | [API Reference](https://firebase.google.com/docs/reference/js/ai)

docs/app-hosting.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<small>
2+
<a href="https://github.com/angular/angularfire">AngularFire</a> &#10097; <a href="../README.md#developer-guide">Developer Guide</a> &#10097; Deploying SSR to Firebase App Hosting
3+
</small>
4+
5+
# Deploying a server-rendered app to Firebase App Hosting
6+
7+
[Firebase App Hosting](https://firebase.google.com/docs/app-hosting) is Firebase's recommended way to deploy a server-side-rendered (SSR) Angular application. It builds your app in Google Cloud Build, runs the Node server, and serves it behind Google's CDN and proxy. This applies to either way of deploying to App Hosting, a connected GitHub repository or `firebase deploy` from your own machine; both build the same way and are affected the same way.
8+
9+
This guide covers one thing that trips up almost every new SSR deployment: **the server can silently stop server-rendering and fall back to client-side rendering (CSR), with no error anywhere obvious.** It explains how to detect that in 30 seconds and how to fix it.
10+
11+
## How to deploy
12+
13+
If you have not deployed yet, follow Firebase's own guides: [Get started with App Hosting](https://firebase.google.com/docs/app-hosting/get-started) to connect a GitHub repository (App Hosting builds and deploys on every push), or [Alternative ways to deploy](https://firebase.google.com/docs/app-hosting/alt-deploy) to deploy with `firebase deploy` from your own machine. Both build your app the same way in Google Cloud Build. The rest of this guide covers an Angular-specific issue you can hit once your app is deployed either way.
14+
15+
## The symptom: SSR silently downgrades to CSR
16+
17+
A freshly deployed Angular SSR app usually *looks* fine in a browser, the page renders and works. But the server may be sending an almost-empty HTML shell and letting the browser do all the rendering. When that happens you lose the whole point of SSR: crawlers and link previews see no content, and first paint on slow devices is worse.
18+
19+
There is no error in the deploy output and no error in the browser. The only trace is in your backend's server logs, which nothing prompts you to check.
20+
21+
App Hosting runs on Cloud Run, not Cloud Functions, so its logs live in Cloud Logging:
22+
23+
- In the Firebase console, open your backend and go to its **Logs** tab, then look at **Runtime logs**.
24+
- From a terminal, use `gcloud`:
25+
26+
```bash
27+
gcloud logging read 'resource.type=cloud_run_revision AND resource.labels.service_name=YOUR_BACKEND_ID' --project YOUR_PROJECT_ID --limit 10
28+
```
29+
30+
See Firebase's [View logs and metrics](https://firebase.google.com/docs/app-hosting/logging) guide for more.
31+
32+
## The 30-second check to run after every deploy
33+
34+
Pick an SSR route (not an SSG/prerendered one) and fetch it:
35+
36+
```bash
37+
curl -s https://YOUR-SITE/ | grep ng-server-context
38+
```
39+
40+
Angular's server renderer stamps a `ng-server-context` attribute on the app's root element:
41+
42+
- `ng-server-context="ssr"` - the route was server-rendered (SSR). This is what you want.
43+
- `ng-server-context="ssg"` - the route was prerendered (SSG). Fine in itself, but not the SSR path this guide is about.
44+
- **No `ng-server-context` at all** - the server returned a client-only shell and the browser is doing all the rendering. This is the silent CSR fallback described above, regardless of how the page looks in a browser.
45+
46+
## Why it happens
47+
48+
Angular's server engine only trusts the `X-Forwarded-*` headers a proxy attaches to a request when it is told to. App Hosting's proxy adds several of these headers (for example `x-forwarded-for` and `x-forwarded-proto`). If Angular does not trust the full set the platform sends, it treats the request as untrusted and de-optimizes to CSR on every request.
49+
50+
<!--
51+
Maintainer note (2026-07-19): the two-step fix below is a workaround for a lag in
52+
Firebase App Hosting's build image. The underlying fix (injecting the full
53+
X-Forwarded-* set into NG_TRUST_PROXY_HEADERS) is already merged upstream in
54+
GoogleCloudPlatform/buildpacks (commit 9346e60b, 2026-06-17) but had not reached
55+
production builders as of 2026-07-19. Once it ships, `npm update` alone suffices
56+
and the trustProxyHeaders step becomes optional; revisit and simplify this guide.
57+
-->
58+
59+
## The Fix
60+
61+
Two steps are needed together.
62+
63+
**1. Update Angular to the latest patch:**
64+
65+
```bash
66+
npm update @angular/core @angular/ssr
67+
```
68+
69+
**2. Turn on proxy-header trust when you create the server engine.** In `src/server.ts`, pass `trustProxyHeaders: true` to `AngularNodeAppEngine`:
70+
71+
```ts
72+
import { AngularNodeAppEngine } from '@angular/ssr/node';
73+
74+
const angularApp = new AngularNodeAppEngine({
75+
trustProxyHeaders: true,
76+
});
77+
```
78+
79+
Redeploy, then run the 30-second check above. You should now see `ng-server-context="ssr"`.
80+
81+
### Why both steps
82+
83+
The two steps address different halves of the same handshake, and neither alone is enough:
84+
85+
- Recent Angular patches let the `trustProxyHeaders` engine option take effect on App Hosting; on older patches a platform environment variable wins instead, so the code option is ignored. The `npm update` gets you onto a patch where the option is honored.
86+
- Even on the latest patch, you still have to *set* the option, so App Hosting's proxy headers are trusted.
87+
88+
This matches Firebase's own guidance. For the current, authoritative version of this fix (including any App Hosting or Angular version notes), see Firebase's [App Hosting troubleshooting guide](https://firebase.google.com/docs/app-hosting/troubleshooting#angular-proxy-trust).
89+
90+
> Note: App Hosting also has an experimental, opt-in local-build deploy option (you build on your own machine, then `firebase deploy`) in which the Firebase CLI applies this proxy-header configuration for you. It is off by default and not a documented, supported workflow, so this guide targets the standard source deploy; apply the fix above.
91+
92+
## Related Angular documentation
93+
94+
- [Angular SSR guide](https://angular.dev/guide/ssr)
95+
- [Configuring trusted proxy headers](https://angular.dev/best-practices/security#configuring-trusted-proxy-headers)

docs/data-connect.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<small>
2+
<a href="https://github.com/angular/angularfire">AngularFire</a> &#10097; <a href="../README.md#developer-guide">Developer Guide</a> &#10097; Data Connect
3+
</small>
4+
5+
# Data Connect
6+
7+
Firebase Data Connect (now known as "Firebase SQL Connect" in the Firebase documentation) is a backend service that pairs a Cloud SQL for PostgreSQL database with GraphQL, generating type-safe SDKs to query and mutate your data.
8+
9+
[Learn more](https://firebase.google.com/docs/data-connect)
10+
11+
## Dependency Injection
12+
13+
As a prerequisite, ensure that `AngularFire` has been added to your project via
14+
```bash
15+
ng add @angular/fire
16+
```
17+
18+
Provide a Data Connect instance in the application's `app.config.ts`. `getDataConnect` takes a connector config that identifies your service, connector, and location; this is generated for you when you set up Data Connect and is also exported from your generated SDK:
19+
20+
```ts
21+
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
22+
import { provideDataConnect, getDataConnect } from '@angular/fire/data-connect';
23+
24+
const connectorConfig = {
25+
connector: 'my-connector',
26+
service: 'my-service',
27+
location: 'us-central1',
28+
};
29+
30+
export const appConfig: ApplicationConfig = {
31+
providers: [
32+
provideFirebaseApp(() => initializeApp({ ... })),
33+
provideDataConnect(() => getDataConnect(connectorConfig)),
34+
...
35+
],
36+
...,
37+
}
38+
```
39+
40+
Next inject `DataConnect` into your component:
41+
42+
```typescript
43+
import { Component, inject } from '@angular/core';
44+
import { DataConnect } from '@angular/fire/data-connect';
45+
46+
@Component({ ... })
47+
export class MyComponent {
48+
private dataConnect = inject(DataConnect);
49+
...
50+
}
51+
```
52+
53+
## Firebase API
54+
55+
AngularFire wraps the Firebase JS SDK to ensure proper functionality in Angular, while providing the same API.
56+
57+
Update the imports from `import { ... } from 'firebase/data-connect'` to `import { ... } from '@angular/fire/data-connect'` and follow the official documentation.
58+
59+
[Getting Started](https://firebase.google.com/docs/data-connect/quickstart)

docs/version-21-upgrade.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Upgrading to AngularFire 21
2+
3+
AngularFire 21 targets **Angular 21** and the **Firebase JS SDK v12**. Most of the upgrade is handled for you by `ng update`.
4+
5+
## Run the update
6+
7+
```bash
8+
ng update @angular/core @angular/cli # move your app to Angular 21 first
9+
ng update @angular/fire # then AngularFire 21
10+
```
11+
12+
`ng update @angular/fire` runs a migration that:
13+
14+
- **Aligns your `firebase` dependency to `^12.4.0`.** AngularFire 21 requires Firebase JS SDK 12. If your app still requested `firebase` 11, npm would install both 11 and 12 side by side, and the two copies reject each other's objects at runtime. The migration updates the dependency and reinstalls so you end up with a single copy. Verify with `npm ls firebase`.
15+
- **Rewrites Vertex AI imports to AI Logic** (see below).
16+
17+
## Vertex AI is now Firebase AI Logic
18+
19+
The Vertex AI module has been renamed to Firebase AI Logic. The `@angular/fire/vertexai` entry point (and the older `@angular/fire/vertexai-preview`) are removed in favor of `@angular/fire/ai`:
20+
21+
| Before (`@angular/fire/vertexai`) | After (`@angular/fire/ai`) |
22+
|---|---|
23+
| `getVertexAI(app?, { location? })` | `getAI(app, { backend: new VertexAIBackend(location?) })` |
24+
| `provideVertexAI` | `provideAI` |
25+
| `VertexAI` | `AI` |
26+
| `VertexAIError` | `AIError` |
27+
| `VertexAIErrorCode` | `AIErrorCode` |
28+
| `VertexAIModel` | `AIModel` |
29+
| `VertexAIInstances` | `AIInstances` |
30+
| `vertexAIInstance$` | `AIInstance$` |
31+
| `VertexAIModule` | `AIModule` |
32+
33+
**`getVertexAI` is not a plain rename.** `getAI` already existed alongside it, and a plain `getAI()` call talks to the Gemini Developer API backend, not to Vertex AI. The equivalent of `getVertexAI()` is `getAI(app, { backend: new VertexAIBackend() })`, which is what the migration writes, so your app keeps calling the Vertex AI backend it was configured, enabled, and billed for. A `location` option moves into the `VertexAIBackend` constructor.
34+
35+
`ng update @angular/fire` rewrites these imports and identifiers for you and logs every `getVertexAI` call it rewrites. Code it cannot rewrite safely (for example when the options are not a literal `{ location }` object or that literal references other rewritten symbols, when the function itself is handed around as a value, when a local declaration in the file reuses an imported symbol's name, or when the file already binds `getAI` or `VertexAIBackend` from a source other than AI Logic) is left in place with a warning. The import path itself still moves to the new entry point, so the leftover code fails to compile there, and nothing changes backends silently. A file where a named `getVertexAI` import has any use that cannot be rewritten keeps every use of its named `getVertexAI` imports in place (namespace-style `ns.getVertexAI(...)` calls are judged per call), and each skipped call is logged. `export * from '@angular/fire/vertexai'` is also left alone (rewriting it would silently rename your re-exported public symbols), so replace it with named re-exports by hand. `VertexAIOptions` was removed rather than renamed (the new `AIOptions` takes a `backend` instead of a `location`), so imports of it are left and warned about. Migrate those sites using the table above. `getGenerativeModel` and `getImagenModel` keep their names.
36+
37+
Imports straight from the Firebase SDK (`firebase/vertexai`, gone in SDK 12) are rewritten to `firebase/ai` under the same rules. The rewrite parses your sources with the `typescript` package (an optional peer dependency of `@angular/fire`). Every Angular workspace already has it, but if the migration warns that it could not be resolved, install `typescript` and re-run. See [ai.md](./ai.md) for current usage.
38+
39+
## Other notes
40+
41+
- **Angular 21 is required.** AngularFire 21 peers `@angular/* ^21.0.0` and does not support Angular 22 (a future AngularFire 22 will).
42+
- The obsolete `@angular/platform-browser-dynamic` peer dependency was removed. No action is needed.

docs/vertexai.md

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)