Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# AI Logic

Firebase AI Logic gives you access to the latest generative AI models from Google: the Gemini models and Imagen models.
Firebase AI Logic gives you access to the latest generative AI models from Google: the Gemini models, including the Gemini image models.

[Learn more](https://firebase.google.com/docs/ai-logic)

Expand Down
20 changes: 19 additions & 1 deletion docs/version-21-upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,28 @@ The Vertex AI module has been renamed to Firebase AI Logic. The `@angular/fire/v

**`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.

`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.
`ng update @angular/fire` rewrites these imports and identifiers for you and logs every `getVertexAI` call it rewrites. `getGenerativeModel` keeps its name.

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.

### What the migration will not rewrite

Code the migration cannot rewrite safely 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. Nothing changes backends silently. It plays safe like this in four situations:

- **Options it cannot read:** when the `getVertexAI` call's options are not a literal `{ location }` object, or that literal references other symbols the migration is also rewriting.
- **The function used as a value:** when `getVertexAI` is stored or passed around rather than called directly.
- **Name collisions:** when a local declaration in the file reuses an imported symbol's name, or the file already gets `getAI` or `VertexAIBackend` from a source other than AI Logic.
- **Wildcard re-exports:** when a file has `export * from '@angular/fire/vertexai'`, that line stays as written, because rewriting it would silently rename your re-exported public symbols. Replace it with named re-exports by hand.

A file where a named `getVertexAI` import is used in a way 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.

### Removed symbols

Two symbols were removed rather than renamed. The migration leaves their imports in place, which breaks loudly, and warns with guidance:

- `VertexAIOptions`: the new `AIOptions` takes a `backend` instead of a `location`, so rebuild the options by hand using the table above.
- `getImagenModel`: Firebase shut the Imagen models down in August 2026 and removed the API in firebase 12.18 (`@firebase/ai` 2.15), so move image generation to the Gemini image models through [`getGenerativeModel`](https://firebase.google.com/docs/ai-logic/generate-images-gemini).

## Other notes

- **Angular 21 is required.** AngularFire 21 peers `@angular/* ^21.0.0` and does not support Angular 22 (a future AngularFire 22 will).
Expand Down
2 changes: 0 additions & 2 deletions src/ai/firebase.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions src/schematics/update/v21/vertexai-to-ai.jasmine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,24 @@ describe('rewriteVertexAIToAI', () => {
expect(warn.calls.mostRecent().args[0]).toContain('no longer exists in the new entry point');
});

it('leaves getImagenModel in place and warns that the Imagen API is gone', () => {
const { context: spiedContext, warn } = contextWithLogSpies();
const source = [
`import { getVertexAI, getImagenModel } from '@angular/fire/vertexai';`,
`export const a = getVertexAI();`,
`export const model = getImagenModel(a, { model: 'imagen-3.0-generate-002' });`,
].join('\n');
const tree = treeWith({ 'src/app/foo.ts': source });

rewriteVertexAIToAI(tree, spiedContext, typescript);

const out = tree.readText('src/app/foo.ts');
expect(out).toContain(`import { getAI, VertexAIBackend, getImagenModel } from '@angular/fire/ai';`);
expect(out).toContain(`getImagenModel(a, { model: 'imagen-3.0-generate-002' });`);
expect(warn).toHaveBeenCalledTimes(1);
expect(warn.calls.mostRecent().args[0]).toContain('Imagen models were shut down');
});

it('reuses an existing VertexAIBackend import instead of adding a second one', () => {
const source = [
`import { VertexAIBackend } from '@angular/fire/ai';`,
Expand Down
1 change: 1 addition & 0 deletions src/schematics/update/v21/vertexai-to-ai/tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const SYMBOL_RENAMES: Record<string, string> = {
// replacement, so the import keeps its name (breaking loudly) and the log explains why.
export const REMOVED_SYMBOL_GUIDANCE: Record<string, string> = {
VertexAIOptions: 'the new AIOptions takes a backend instead of a location, rebuild the options by hand',
getImagenModel: 'the Imagen models were shut down in August 2026 and firebase 12.18 removed the API, move image generation to the Gemini image models through getGenerativeModel',
};

export const GET_VERTEX_AI = 'getVertexAI';
Expand Down
8 changes: 7 additions & 1 deletion tools/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,13 @@ ${exportedZoneWrappedFns}
await writeFile(filePath, fileOutput);
};
return Promise.all([
reexport('ai', 'firebase', 'firebase/ai', tsKeys<typeof import('firebase/ai')>()),
reexport('ai', 'firebase', 'firebase/ai', tsKeys<typeof import('firebase/ai')>(), {
// Removed in @firebase/ai 2.15.0 (firebase 12.18.0), which the ^12.4.0 range
// resolves for fresh installs. A named import here would make consumer builds
// fail on that version, so only re-export it through the star export, which
// tracks whichever firebase is installed.
getImagenModel: null,
}),
reexport('analytics', 'firebase', 'firebase/analytics', tsKeys<typeof import('firebase/analytics')>(), {
isSupported: { blockUntilFirst: false },
logEvent: { blockUntilFirst: false, logLevel: LogLevel.VERBOSE },
Expand Down
Loading