Firebase AI Logic in Angular: Client-Side Gemini Without a…
    Neura Market
    Neura Market
    /Gemini
    Marketplace
    Directories
    Resources
    Gemini
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityDeepSeekDeepSeekCoPilotCoPilotStable DiffusionStable DiffusionMidjourneyMidjourney
    OverviewRulesPromptsMCPsAgentsGamesBlogVideosGuidesCoursesCommunityGemsExtensionsTrending
    GeminiBlogFirebase AI Logic in Angular: Client-Side Gemini Without a Custom Backend
    Back to Blog
    Firebase AI Logic in Angular: Client-Side Gemini Without a Custom Backend
    ai

    Firebase AI Logic in Angular: Client-Side Gemini Without a Custom Backend

    Wayne Gakuo September 15, 2026
    2 views

    Since I last wrote Building AI-powered e-commerce applications using Angular & Firebase AI Logic...

    Since I last wrote Building AI-powered e-commerce applications using Angular & Firebase AI Logic (formerly Vertex AI in Firebase) in 2025, so much has changed that this article may look like a complete rewrite.

    Firebase AI Logic is the successor to Vertex AI in Firebase (May 2025). This post covers the Angular setup only. For the full rename, new APIs, and migration from firebase/vertexai, see Vertex AI in Firebase is now Firebase AI Logic — What Actually Changed.

    Official Firebase docs cover each piece, but the order matters. This guide follows the sequence that actually works. We use the modular firebase JS SDK + Angular DI, so this works on Angular 18+.


    Why Firebase AI Logic in web apps

    Most Gemini tutorials show either AI Studio + a raw API key or a custom Node/Python proxy you host and secure yourself. Firebase AI Logic sits in between: Gemini runs from your Angular app in the browser, but requests go through Firebase's managed path and not a DIY backend you maintain.

    What you get on web:

    BenefitWhy it matters
    No custom AI backendCall generateContent() from a service; skip building Express/Cloud Functions just to hide an API key
    App Check attestationProves traffic comes from your real app (reCAPTCHA Enterprise in prod, debug tokens on localhost) — required for production AI Logic on web
    One Firebase projectSame Console for Hosting, Auth, Firestore, Remote Config, and AI monitoring
    Gemini Developer API pathGoogleAIBackend(): fast onboarding, Spark plan for prototypes, Console wizard provisions APIs for you
    Upgrade pathSwitch to AgentPlatformBackend() later if you need enterprise Vertex/Agent Platform features; often a one-line backend change

    Good fit for web apps:

    • Shopping assistants, support chat, on-page copilots
    • Multi-turn chat and function calling (tools that call your existing Angular services)
    • Features where latency matters; inference starts from the client without an extra hop through your server

    When to use something else:

    • Sensitive prompts or secrets: keep those on the server (Genkit, Cloud Functions)
    • Heavy RAG over private corpora: server-side retrieval is usually safer and more flexible
    • Billing/abuse control at the edge: combine App Check enforcement with Firebase Console monitoring; add server gates for high-risk actions

    For ByteWise, the agent reads inventory and updates the cart via function calling; still client-side AI Logic, with business logic in Angular services. This guide stops at your first generateContent(); the ByteWise repo goes further.


    What you are building

    Firebase Console (AI Logic + App Check + API keys)
            ↓
    firebase.config.ts          ← credentials
    firebase-ai.ts              ← initializeApp + App Check + getAI (providers)
    app.config.ts               ← register providers once
    ai.service.ts               ← inject FIREBASE_AI → generateContent()
    

    You only create two new Firebase-specific files beyond a standard Angular app:

    FilePurpose
    src/environments/firebase.config.tsfirebaseConfig + reCAPTCHA site key
    src/app/firebase/firebase-ai.tsBootstrap: tokens, App Check, provideFirebaseAI()

    Everything else is small edits to files you already have (app.config.ts, index.html, one service).


    Prerequisites

    • Angular 18+ (standalone, ApplicationConfig style)
    • Node.js LTS
    • A Google account and a Firebase project
    • firebase >= 12.19.0 (required for current Gemini + App Check behaviour)
    npm install firebase@^12.19.0
    

    Part 1: Firebase Console (do this before writing any code)

    1. Create a project and web app
    1. Firebase Console → Create a new Firebase project
    2. Add app → Web (</>)
    3. Copy the firebaseConfig object — you will paste it in Part 2
    2. Enable Firebase AI Logic (early)
    1. AI Services → AI Logic → Get started
    2. Choose Gemini Developer API and finish the setup wizard. Ensure to enable the APIs recommended and AI monitoring.

    Wait 5–10 minutes, then in Google Cloud console (same project ID as Firebase): APIs & Services → Enabled APIs & services → scroll past the charts to the API table → use Filter to confirm Firebase AI Logic API and Gemini API are listed. Firebase's wizard labels the second one Gemini Developer API; GCP now shows Gemini API (generativelanguage.googleapis.com). You may also see Gemini for Google Cloud API when filtering Gemini — that is for Gemini inside the Cloud Console and is not required for Firebase AI Logic in your Angular app.

    Skipping this step is the most common cause of 403 "The caller does not have permission" later.

    3. reCAPTCHA Enterprise + App Check

    3a. Create a reCAPTCHA Enterprise key

    1. Google Cloud (same project) → Security → Fraud Defense → Enable reCAPTCHA Enterprise API
    2. Select Keys on the tab → Create key → Input any Display name of your choice → Website
    3. Domains: add domains that production only. Do not add localhost. For example:
      • <project-id>.web.app
      • <project-id>.firebaseapp.com
      • Any custom domain you use later
    4. Click on Create Key
    5. After creation, copy the site key. This key starts with something like 6L...

    3b. Register App Check

    1. Firebase Console → Security → App Check → Click on the Apps tab → Click on your web app → reCAPTCHA Enterprise → paste site key (from Step 3a). You can leave the default configurations as they are.
    2. APIs tab → Firebase AI Logic. You will find Monitoring and Baseline Protection have already been enabled (Basic - Enforced). However, you can set up additional checks if you want such as Replay Protection.
    4. Browser API key restrictions
    1. Google Cloud → APIs & Services → Credentials
    2. Open the Browser key matching your firebaseConfig.apiKey
    3. API restrictions: You will find about 25 APIs already allowed on that project and ensure you allow Firebase AI Logic API and Firebase App Check API if not already allowed.
    4. Application restrictions: None while developing on localhost

    Part 2: Angular configuration

    Step 1: Generate Angular environment variables files

    You can generate your Angular environment files using the command:

    ng generate environments
    
    Step 2: src/environments/firebase.config.ts

    Inside the environment folder, create a file with the name firebase.config.ts and copy the code snippet below. Replace the YOUR_ values with the actual values from your Firebase project Settings (scroll all the way down to the SDK setup and configuration section).

    The recaptchaEnterpriseSiteKey is the same as the one in Part 1: Step 3a: Google Cloud (same project) → Security → Fraud Defense → Keys → Copy the already created key.

    import type { FirebaseOptions } from 'firebase/app';
    
    export const firebaseConfig: FirebaseOptions = {
      apiKey: 'YOUR_API_KEY',
      authDomain: 'YOUR_PROJECT.firebaseapp.com',
      projectId: 'YOUR_PROJECT_ID',
      storageBucket: 'YOUR_PROJECT.firebasestorage.app',
      messagingSenderId: 'YOUR_SENDER_ID',
      appId: 'YOUR_APP_ID',
    };
    
    export const recaptchaEnterpriseSiteKey = 'YOUR_RECAPTCHA_SITE_KEY';
    
    Step 3: src/environments/environment.model.ts

    Create environment.model.ts — one shared type for production and development. appCheckDebugToken is optional so production omits it, while firebase-ai.ts can still reference environment.appCheckDebugToken without IDE TS2339 errors (your editor type-checks environment.ts, not the dev file Angular swaps in at build time).

    import type { FirebaseOptions } from 'firebase/app';
    
    export interface AppEnvironment {
      production: boolean;
      firebaseConfig: FirebaseOptions;
      recaptchaEnterpriseSiteKey: string;
      /** Dev/CI only — set in `environment.development.ts`, omit in `environment.ts` */
      appCheckDebugToken?: boolean | string;
    }
    
    Step 4: environment.ts and environment.development.ts

    src/environments/environment.ts (production — used by ng build):

    import { firebaseConfig, recaptchaEnterpriseSiteKey } from './firebase.config';
    import type { AppEnvironment } from './environment.model';
    
    export const environment: AppEnvironment = {
      production: true,
      firebaseConfig,
      recaptchaEnterpriseSiteKey,
    };
    

    src/environments/environment.development.ts (local dev — swapped in by ng serve):

    import { firebaseConfig, recaptchaEnterpriseSiteKey } from './firebase.config';
    import type { AppEnvironment } from './environment.model';
    
    export const environment: AppEnvironment = {
      production: false,
      firebaseConfig,
      recaptchaEnterpriseSiteKey,
      appCheckDebugToken: true,
    };
    

    Confirm angular.json has fileReplacements under the development build configuration ( ng generate environments usually adds this):

    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.development.ts"
      }
    ]
    

    Always import the alias path in app code — never environment.development directly:

    import { environment } from '../../environments/environment';
    

    NOTE: On ng serve, the CLI substitutes environment.development.ts wherever you import environment.ts. Production builds use the real environment.ts with no debug token.

    Step 5: src/app/firebase/firebase-ai.ts

    Create a file with the name firebase-ai.ts under a folder firebase.

    import {
      inject,
      InjectionToken,
      makeEnvironmentProviders,
      PLATFORM_ID,
      provideAppInitializer,
      type EnvironmentProviders,
    } from '@angular/core';
    import { isPlatformBrowser } from '@angular/common';
    import { getAI, GoogleAIBackend, type AI } from 'firebase/ai';
    import { initializeApp, type FirebaseApp } from 'firebase/app';
    import {
      CustomProvider,
      initializeAppCheck,
      ReCaptchaEnterpriseProvider,
      type AppCheck,
    } from 'firebase/app-check';
    import { environment } from '../../environments/environment';
    
    export const FIREBASE_AI = new InjectionToken<AI>('FIREBASE_AI');
    const FIREBASE_APP_CHECK = new InjectionToken<AppCheck>('FIREBASE_APP_CHECK');
    
    const firebaseApp = initializeApp(environment.firebaseConfig);
    
    function initAppCheck(firebaseApp: FirebaseApp, platformId: object): AppCheck {
      const isBrowser = isPlatformBrowser(platformId);
    
      if (isBrowser && !environment.production) {
        (globalThis as typeof globalThis & { FIREBASE_APPCHECK_DEBUG_TOKEN?: boolean | string })
          .FIREBASE_APPCHECK_DEBUG_TOKEN ??= environment.appCheckDebugToken ?? true;
      }
    
      if (!isBrowser) {
        return initializeAppCheck(firebaseApp, {
          provider: new CustomProvider({
            getToken: async () => ({
              token: 'ssr-placeholder',
              expireTimeMillis: Date.now() + 60 * 60 * 1000,
            }),
          }),
          isTokenAutoRefreshEnabled: false,
        });
      }
    
      return initializeAppCheck(firebaseApp, {
        provider: new ReCaptchaEnterpriseProvider(environment.recaptchaEnterpriseSiteKey),
        isTokenAutoRefreshEnabled: true,
      });
    }
    
    export function provideFirebaseAI(): EnvironmentProviders {
      return makeEnvironmentProviders([
        {
          provide: FIREBASE_APP_CHECK,
          useFactory: (platformId: object) => initAppCheck(firebaseApp, platformId),
          deps: [PLATFORM_ID],
        },
        {
          provide: FIREBASE_AI,
          useFactory: (_appCheck: AppCheck): AI =>
            getAI(firebaseApp, {
              backend: new GoogleAIBackend(),
              useLimitedUseAppCheckTokens: environment.production,
            }),
          deps: [FIREBASE_APP_CHECK],
        },
        // Eager-init App Check on startup — prints the debug token in DevTools
        // immediately so you can register it in Firebase Console before Part 3.
        provideAppInitializer(() => {
          inject(FIREBASE_APP_CHECK);
        }),
      ]);
    }
    
    Step 6: src/app/app.config.ts
    import { ApplicationConfig } from '@angular/core';
    import { provideRouter } from '@angular/router';
    import { routes } from './app.routes';
    import { provideFirebaseAI } from './firebase/firebase-ai';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideRouter(routes),
        provideFirebaseAI(),
      ],
    };
    
    Step 7: Localhost debug token — src/index.html

    Add this inside the <body> element, right before <app-root>.

    <script>
      if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') {
        self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
      }
    </script>
    
    Step 8: Run locally and capture the debug token
    ng serve
    

    Open http://localhost:4200 (the URL the Angular CLI prints in the terminal).

    Where the token appears: the Firebase SDK logs it when initializeAppCheck() runs with the debug provider active. Open DevTools → Console:

    Search/filter for AppCheck debug token or debug token

    You should see a line similar to:

    Firebase App Check debug token: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    

    Copy the UUID (without quotes), then register it:

    Firebase Console → App Check → Apps → your web app → ⋮ menu → Manage debug tokens → Add debug token → Give the debug token any name of your choice → paste → save → hard-refresh the app (Ctrl+Shift+R).

    NOTE: The debug token is not in environment.ts. It's minted by the SDK and printed in the Console once App Check initializes on the client. The debug token is ONLY for use during development. Production must use reCAPTCHA, not debug tokens.


    Part 3: Your first generateContent

    Step 1: src/app/services/ai.service.ts
    import { inject, Injectable } from '@angular/core';
    import { getGenerativeModel } from 'firebase/ai';
    import { FIREBASE_AI } from '../firebase/firebase-ai';
    
    @Injectable({ providedIn: 'root' })
    export class AiService {
      private readonly ai = inject(FIREBASE_AI);
    
      async ask(prompt: string): Promise<string> {
        const model = getGenerativeModel(this.ai, { model: 'gemini-3.5-flash' });
        const result = await model.generateContent(prompt);
        return result.response.text();
      }
    }
    
    Step 2: Call it from a component

    Generate a dedicated AI Demo component with the Angular CLI, or wire the call into your root App component.

    ng generate component ai-demo --inline-template --skip-tests
    
    import { Component, inject, signal } from '@angular/core';
    import { AiService } from '../services/ai.service';
    
    @Component({
      selector: 'app-ai-demo',
      template: `
        <button (click)="run()" [disabled]="loading()">
          {{ loading() ? 'Please wait…' : 'Ask Gemini' }}
        </button>
        @if (error()) {
          <p role="alert">{{ error() }}</p>
        }
        @if (reply()) {
          <pre>{{ reply() }}</pre>
        }
      `,
      styleUrl: './ai-demo.scss',
    })
    export class AiDemo {
      private readonly ai = inject(AiService);
      readonly loading = signal(false);
      readonly reply = signal('');
      readonly error = signal('');
    
      async run(): Promise<void> {
        this.loading.set(true);
        this.error.set('');
        this.reply.set('');
        try {
          this.reply.set(await this.ai.ask('Say hello in one sentence.'));
        } catch (err) {
          this.error.set(
            err instanceof Error ? err.message : 'Something went wrong. Check the console.',
          );
        } finally {
          this.loading.set(false);
        }
      }
    }
    

    Render it from src/app/app.html:

    <app-ai-demo />
    

    Import AiDemo in src/app/app.ts — Angular components are standalone by default and must be listed in the parent imports array:

    import { Component } from '@angular/core';
    import { AiDemo } from './ai-demo/ai-demo';
    
    @Component({
      selector: 'app-root',
      imports: [AiDemo],
      templateUrl: './app.html',
      styleUrl: './app.scss',
    })
    export class App {}
    

    Without that import, <app-ai-demo /> will fail at compile time with an unknown element error.

    Run ng serve and click on the Ask Gemini button in the rendered UI on http://localhost:4200


    Part 4: Verify it worked

    Click Ask Gemini. If you get text back — not a 403 — your setup works. That is the pass/fail check.

    On first load, the console should show no App Check token fetch failed, and you should have registered the debug token from Part 2, Step 8. Optional: in DevTools → Network, filter firebasevertexai and confirm a POST to :generateContent returns 200. Do not worry if you cannot spot X-Firebase-AppCheck — the header is easy to miss, and Gemini succeeding is what matters.

    403 The caller does not have permission? Re-run AI Logic → Get started, confirm the debug token is registered, confirm the Browser key allowlist includes Firebase AI Logic API + Firebase App Check API, then wait a few minutes and hard-refresh.


    Part 5: What you can add next

    FeatureSDK entry point
    Multi-turn chatstartChat() on a generative model
    Function callingtools + FunctionCallingConfig on the model
    StreaminggenerateContentStream()
    System instructionssystemInstruction in model config

    For a full function-calling example, see ByteWise ai.service.ts.


    Conclusion

    We are at an inflection point where developers can build intelligent web experiences, powered by Large Language Models. Firebase AI Logic provides this infrastructure with a free tier on the Gemini Developer API and Agent Platform Gemini API for enterprise-level use cases.

    If you want these capabilities where latency matters, Firebase AI Logic will be your best bet, while offering you security and abuse prevention for your production apps.

    To see Firebase AI Logic in action in e-commerce applications, check out Bytewise Shop, a fictional tech gadget shop I built to demonstrate the use of tool calling on actions such as add to cart, check inventory, clearing cart, all using natural language.


    File checklist

    • src/environments/firebase.config.ts — new
    • src/environments/environment.model.ts — new
    • src/environments/environment.ts — production values
    • src/environments/environment.development.ts — add appCheckDebugToken
    • src/app/firebase/firebase-ai.ts — new
    • src/app/app.config.ts — add provideFirebaseAI()
    • src/index.html — localhost debug script
    • src/app/services/ai.service.ts — new
    • AiDemo component + import in app.ts

    Related links

    • Vertex AI in Firebase is now Firebase AI Logic — What Actually Changed — companion article (rename, migration, what's new)
    • Firebase AI Logic overview
    • App Check with AI Logic (web)

    Tags

    aifirebasegeminiangular

    Comments

    More Blog

    View all
    [AI in Practice] Upgrading from Gemini 3.5/3.6 to Gemini 4 Argon: Migration Notes and Pitfalls for LINE Bot Developersai

    [AI in Practice] Upgrading from Gemini 3.5/3.6 to Gemini 4 Argon: Migration Notes and Pitfalls for LINE Bot Developers

    Background I have a LINE Bot that I use every day, linebot-helper-python. I use it daily...

    E
    Evan Lin
    Six Months After Cloud Next ‘26: A Builder’s Tour of the Gemini Enterprise Agent Platformgooglecloud

    Six Months After Cloud Next ‘26: A Builder’s Tour of the Gemini Enterprise Agent Platform

    What actually shipped across Build, Scale, Govern, and Optimize — and what I'd tell a team starting...

    J
    Jonathan Zhuo
    1
    AlphaEvolve and Gemini: Autonomous Algorithm Discovery for Unified Disaster Predictionai

    AlphaEvolve and Gemini: Autonomous Algorithm Discovery for Unified Disaster Prediction

    📄 Published Paper (Open Access on Zenodo): Autonomous Discovery of Unified Multi-Hazard Prediction...

    T
    Tanaike
    1
    LangChainJS and Gemini 4 Argon: What's here and what's coming?ai

    LangChainJS and Gemini 4 Argon: What's here and what's coming?

    Google has released the latest version in the Gemini family, Gemini 4 Argon, and I was fortunate...

    A
    Allen Firstenberg
    Nobody’s winning the AI race yetai

    Nobody’s winning the AI race yet

    By Ryan Swift Yesterday, Google finally released its Gemini 4 Argon model for public use. It’s...

    R
    Ryan Swift
    1
    I got Jev to zero mistakes. I'm still using Flash-Lite.ai

    I got Jev to zero mistakes. I'm still using Flash-Lite.

    Jev is a brilliant decision model. Gemini Flash-Lite is the model nobody talks about, and it’s fast,...

    S
    Swift
    1

    Stay up to date

    Get the latest Gemini prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for Gemini and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Games
    • Blog
    • Videos
    • Guides
    • Courses
    • Community
    • Gems
    • Extensions

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.

    Neura Market

    Custom AI Systems & Services

    Our team of experienced AI builders will help build custom AI systems, workflows, and solutions.

    Request custom work

    Ready-made automations for this

    Workflows from the Neura Market marketplace related to this Gemini resource

    • Automate Blog Post Creation from WooCommerce Products Using OpenAIn8n · $9.99 · Related topic
    • Building a RAG Chatbot for Movie Recommendations with Qdrant and OpenAIn8n · $14.99 · Related topic
    • Create Secure Interactive Applications with WhatsApp Flows and End-to-End Encryptionn8n · $9.99 · Related topic
    • E-commerce Product Fine-tuning With Bright Data and OpenAIn8n · $9.99 · Related topic
    Browse all workflows