Skip to content
Draft
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
67 changes: 67 additions & 0 deletions docs/app-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,73 @@ export class AppCheckComponent {
}
```

## Server-side rendering

App Check's reCAPTCHA providers need a browser. So while a page renders on the server, AngularFire does not call the function you pass to `provideAppCheck`, and no App Check instance is created there. On the server, `inject(AppCheck)` returns `null`, although its type says `AppCheck`. Code that runs on both the server and the browser should check the platform before using it.

### Firebase requests made during server rendering

With no App Check instance on the server, requests to Firebase made while the server renders a page carry no App Check token. If you [enforce App Check](https://firebase.google.com/docs/app-check/enable-enforcement) for a Firebase product, those requests are rejected. Firebase's recommended fix is to hand a token from the browser to the server and pass it to `initializeServerApp` as `appCheckToken`, described in [Use App Check in SSR environments](https://firebase.google.com/docs/web/ssr-apps#use-app-check).

### Running App Check during server rendering

If your app runs App Check on the server on purpose, with a provider that works outside the browser such as a `CustomProvider` backed by the Firebase Admin SDK, provide `APP_CHECK_ON_SERVER` in the server-only config:

```ts
// app.config.server.ts
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
import { provideServerRendering, withRoutes } from '@angular/ssr';
import { APP_CHECK_ON_SERVER } from '@angular/fire/app-check';
import { appConfig } from './app.config';
import { serverRoutes } from './app.routes.server';

const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(withRoutes(serverRoutes)),
{ provide: APP_CHECK_ON_SERVER, useValue: true },
]
};

export const config = mergeApplicationConfig(appConfig, serverConfig);
```

The function passed to `provideAppCheck` then runs on the server too, so it has to choose a provider that works there.

### AngularFire 21.0.0-rc.1 and earlier

These releases run App Check during server rendering, so the setup in [Dependency Injection](#dependency-injection) fails with `ReferenceError: document is not defined`. Keep `provideAppCheck` out of the config the server uses by moving it into a config only the browser loads:

```ts
// app.config.browser.ts
import { ApplicationConfig, inject, mergeApplicationConfig } from '@angular/core';
import { FirebaseApp } from '@angular/fire/app';
import { provideAppCheck, initializeAppCheck, ReCaptchaV3Provider } from '@angular/fire/app-check';
import { appConfig } from './app.config';

const browserConfig: ApplicationConfig = {
providers: [
provideAppCheck(() => initializeAppCheck(inject(FirebaseApp), {
provider: new ReCaptchaV3Provider(/* configuration */),
})),
]
};

export const config = mergeApplicationConfig(appConfig, browserConfig);
```

Then bootstrap the browser with that config in `main.ts`:

```ts
import { bootstrapApplication } from '@angular/platform-browser';
import { config } from './app/app.config.browser';
import { App } from './app/app';

bootstrapApplication(App, config)
.catch((err) => console.error(err));
```

The server then has no `AppCheck` provider at all, so inject it with `inject(AppCheck, { optional: true })`, which returns `null` on the server as later releases do.

## Firebase API

AngularFire wraps the Firebase JS SDK to ensure proper functionality in Angular, while providing the same API.
Expand Down
Loading