Tips for resolving the (appCheck/already-initialized) issue in Angular 17

After setting up a new angular ssr project, I integrated @angular/fire using schematics. The project interacts with firestore, storage, and authentication services. To enhance security, I configured app-check services and added my app debug token to the firebase console.

Below is how I initialized Firebase in my app.config.ts:

export const appConfig: ApplicationConfig = {
  providers: [
    importProvidersFrom(
      provideFirebaseApp(() => initializeApp(environment.firebase)),
      provideAppCheck(() =>
        initializeAppCheck(getApp(), {
          provider: new ReCaptchaEnterpriseProvider(environment.siteKey),
          isTokenAutoRefreshEnabled: true,
        })
      )
    ),
  ]
}

The first time I run npm start, an error is displayed as shown here.

Upon reloading the page without any code changes, everything works fine. However, modifying the code and then reloading the page triggers another error as seen here.

This error persists until I terminate the terminal process and restart npm start.

I attempted checking for existing apps during appCheck initialization, but it did not resolve the issue:

provideAppCheck(() =>
  initializeAppCheck(
    getApps().length === 0 
      ? initializeApp(environment.firebase)
      : getApp(), 
    {
      provider: new ReCaptchaEnterpriseProvider(environment.siteKey),
      isTokenAutoRefreshEnabled: true,
    }
  )
)

Answer №1

The issue encountered involves the interaction between @angular/fire/app-check and SSR in Angular versions 17 to 18. The error message document is not defined occurs because the server tries to initialize AppCheck, which can only be done on the browser side, not on the server.

To resolve this issue, you need to create a service similar to the following example, using a custom provider:

import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import {
  CustomProvider,
  ReCaptchaEnterpriseProvider,
} from '@angular/fire/app-check';

@Injectable({
  providedIn: 'root',
})
export class RecaptchaBrowser {
  constructor(@Inject(PLATFORM_ID) private platformId: string) {}

  provider(siteKey: string) {
    return isPlatformBrowser(this.platformId)
      ? new ReCaptchaEnterpriseProvider(siteKey)
      : new CustomProvider({
          getToken: () => new Promise(() => {}),
        });
  }
}

Then, proceed to initialize the app with your custom provider as shown below:

provideAppCheck((injector) =>
  initializeAppCheck(getApp(), {
    provider: injector
      .get(RecaptchaBrowser)
      .provider(environment.reCaptchaSiteKey),
    isTokenAutoRefreshEnabled: true,
  }),
),

Additionally, following Naren's advice, it is crucial to remove importProvidersFrom( if you are working with Angular versions 17 or 18.

Answer №2

Would it be possible to remove the importProvidersFrom statement for firebase providers in this code snippet?

export const appConfig: ApplicationConfig = {
  providers: [
      provideFirebaseApp(() => initializeApp(environment.firebase)),
      provideAppCheck(() =>
        initializeAppCheck(getApp(), {
          provider: new ReCaptchaEnterpriseProvider(environment.siteKey),
          isTokenAutoRefreshEnabled: true,
        })
      )
  ]
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How do I configure an Angular project in Nx Workspace to be served as HTTPS?

Currently, I have an nx workspace set up with an Angular project and a NestJS backend. Everything is compiling and functioning properly. Now, the need has arisen to locally host the Angular app using https for development purposes. Typically, I would use t ...

Is it feasible to broaden an interface in Typescript without including a specific type?

import React from "react"; interface a_to_e { a?: string; b?: string; c?: string; d?: string; e?: string; } interface a_to_e_without_c extends a_to_e { // I want to include properties a~e except for c } function Child(props: a_to_e_without_c ...

Using `rootDirs` in a monorepo setting results in unnecessary subfolders like `src` being generated in the `outDir`

I am in the process of planning a monorepo TypeScript project structured as follows: / (root) +--backend/ | +-src/ | \-tsconfig.json +--shared/ | \-src/ \--frontend/ \-src/ The tsconfig.json file looks like this: { "compil ...

What benefits does redux-thunk offer?

Why is redux-thunk necessary? It seems like using a thunk just adds an extra layer of complexity by wrapping expressions and using middleware. The sample code from redux-thunk further confuses the process. import thunk from 'redux-thunk'; // No ...

Guide to utilizing constructor options with a TypeScript Vue class

When reviewing the code snippet provided at https://i.sstatic.net/vfDZc.png, a compilation error occurs. An error is displayed in C:/dev/AscendXYZ/Ascend.Wammo.RadarIngestor/apps/Ascend.Wammo.Dashboard/src/components/BirdControlMap.tsx 32:1 Unable to resol ...

The utility of commander.js demonstrated in a straightforward example: utilizing a single file argument

Many developers rely on the commander npm package for command-line parsing. I am considering using it as well due to its advanced functionality, such as commands, help, and option flags. For my initial program version, I only require commander to parse ar ...

Issue with ion-datetime component causing unexpected value changes when both maximum and minimum values are set

My current project includes the use of ion-datetime. Here are some details regarding the Ionic version being used: Ionic: Ionic CLI : 5.4.16 Ionic Framework : ionic-angular 3.9.5 @ionic/app-scripts : 3.2.2 Below is a snippet showcasi ...

What is the process for launching the application directly to a specific component?

Hello everyone, I'm currently developing my app using Angular and have just started implementing routing. My question is, how can I ensure that the HomeComponent loads automatically when the site is opened? ...

What are the steps for running an Angular 7 application on both Android and iOS devices?

Currently in the process of developing an application using Angular 7. Any tips on ensuring optimal performance on mobile devices? The app functions smoothly on desktops in aot mode; however, loading time on Android devices is exceedingly slow (approximat ...

Choose the desired option from Angular 7 / Ionic 4 dropdown menu

I am facing an issue with a piece of code that creates dynamic drop-down select options. I need to retrieve the selected values from these items. The loop in the code generates 3 to 5, or sometimes even more, different dropdowns based on API data. My goa ...

How can we enforce that only a certain type of ReactElement is allowed to be passed as props to a Component in TypeScript?

eslint and vscode seem to have trouble detecting validation errors when passing incompatible ReactElement types. Despite searching through documentation and examples, I haven't been able to find a solution that works. // Footer.tsx export interface ...

Creating an Http interceptor in Ionic 3 and Angular 4 to display a loading indicator for every API request

One of my current challenges involves creating a custom HTTP interceptor to manage loading and other additional functions efficiently. Manually handling loading for each request has led to a considerable increase in code. The issue at hand: The loader is ...

Params are not being sent by Angular HttpRequest

I have been attempting to pass parameters in a basic GET request using HttpRequest, but it seems that the parameters are not being sent. let params = new HttpParams(); params.set("page", "4"); let req = new HttpRequest<any>( &q ...

Transformation of entryComponents to Angular 9 Ivy

@Component({ selector: 'dynamic', template: '<ng-template *ngFor="let portal of portals" [cdkPortalOutlet]="portal"></ng-template>', // entryComponents before Ivy entryComponents: [Component1, Component2, Compone ...

What is the best way to sort my chat groups based on the most recent update when working with denormalized data in Firebase?

I am currently in the process of creating a chat application using Firebase (along with AngularJS) and my data structure resembles the one outlined on this Firebase documentation page. This setup is great for avoiding unnecessary data retrieval, but I am f ...

Azure Function responding with a 401 error code upon passing parameters through a proxy

I have a situation where I am working with an Angular service that includes a GET request with parameters currentPage and postsPerPage. In my efforts to pass these parameters to an Azure function, I came across a tutorial advising me to set up proxies. Wh ...

Exploring the distinctions between types and classes through type hinting

It seems that I am facing some challenges with this task and the reason is unclear to me switch (typeof request) { case 'EnrollmentRequest': The type '"EnrollmentRequest"' cannot be compared to the type '"string" | "number" | ...

Prevent all dates from being selected except for the last day of every month in the Angular Material Calendar component

Is it possible to restrict all dates except the final day of each month with Angular Material? I need users to only be able to select this particular date. There is a [matDatepickerFilter] property, but it seems to work only for a specific list of dates. ...

The expandable column headers in Primeng are mysteriously missing

I'm facing an issue with my expandable row in Angular2 using Primeng2, where the column headers for the expandable columns are not displaying. Below is the code snippet of my table with expandable rows: <p-dataTable [value]="activetrucks" expanda ...

Issue: Unable to locate module ' Stack trace: - /var/runtime/index.mjs when running Lambda function generated using Terraform and Node.js version 18 or higher

My Terraform setup involves a Lambda function with a Node.js version of >= 18, following the steps outlined in this helpful article. However, upon attempting to invoke the Lambda function, CloudWatch throws the following error: "errorType" ...