-
Notifications
You must be signed in to change notification settings - Fork 89
docs: Update Firebase authentication setup and configuration documentation #472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
b8f4ff2
docs: Update Firebase authentication setup and configuration document…
Zfinix f3a991e
docs: Update Firebase authentication setup and configuration document…
Zfinix f5780ff
docs: Add Firebase authentication setup images for improved documenta…
Zfinix 8826a04
docs: Enhance Firebase authentication documentation with setup prereq…
Zfinix f53cb42
docs: Clarify Firebase authentication setup instructions, including p…
Zfinix 558e587
docs: Add troubleshooting section for `Firebase.initializeApp()` chan…
Zfinix e6faa5c
Update docs/06-concepts/11-authentication/04-providers/06-firebase/01…
Zfinix e164e4e
docs: Update Firebase setup documentation with improved instructions …
Zfinix 3e6d6be
Merge remote-tracking branch 'origin/main' into chore/update-sign-in-…
Zfinix 414acf0
Merge branch 'chore/update-sign-in-with-firebase-docs' of https://git…
Zfinix af20f05
docs: Update Firebase documentation
Zfinix 8da4828
docs: Add new Firebase account creation callbacks and clock skew tole…
Zfinix 8d8bf5f
docs: Enhance Firebase customization instructions with secure credent…
Zfinix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
365 changes: 229 additions & 136 deletions
365
docs/06-concepts/11-authentication/04-providers/06-firebase/01-setup.md
Large diffs are not rendered by default.
Oops, something went wrong.
152 changes: 0 additions & 152 deletions
152
docs/06-concepts/11-authentication/04-providers/06-firebase/02-configuration.md
This file was deleted.
Oops, something went wrong.
152 changes: 152 additions & 0 deletions
152
docs/06-concepts/11-authentication/04-providers/06-firebase/02-customizations.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| # Customizations | ||
|
|
||
| This page covers additional configuration options for the Firebase identity provider beyond the basic setup. | ||
|
|
||
| ## Loading credentials with FirebaseIdpConfig | ||
|
|
||
| The [setup guide](./setup) uses `FirebaseIdpConfigFromPasswords`, which loads the service account key from `passwords.yaml` for you. When you need to load credentials from a different source (a file path, a secrets manager, or just a project ID), use `FirebaseIdpConfig` directly and pass a `FirebaseServiceAccountCredentials` instance. | ||
|
|
||
| `FirebaseServiceAccountCredentials` provides four constructors. These are the only supported ways to construct it: | ||
|
|
||
| **From a JSON string** (use this when reading the JSON from a secrets manager or environment variable): | ||
|
|
||
| ```dart | ||
| final firebaseIdpConfig = FirebaseIdpConfig( | ||
| credentials: FirebaseServiceAccountCredentials.fromJsonString( | ||
| pod.getPassword('firebaseServiceAccountKey')!, | ||
| ), | ||
| ); | ||
| ``` | ||
|
|
||
| **From a JSON file** (useful for local development or when secrets are mounted as files): | ||
|
|
||
| ```dart | ||
| import 'dart:io'; | ||
|
|
||
| final firebaseIdpConfig = FirebaseIdpConfig( | ||
| credentials: FirebaseServiceAccountCredentials.fromJsonFile( | ||
| File('config/firebase_service_account_key.json'), | ||
| ), | ||
| ); | ||
| ``` | ||
|
|
||
| **From a JSON map** (useful when credentials are assembled programmatically, for example by pulling each field from `passwords.yaml` or a secrets manager): | ||
|
|
||
| ```dart | ||
| final firebaseIdpConfig = FirebaseIdpConfig( | ||
| credentials: FirebaseServiceAccountCredentials.fromJson({ | ||
| 'type': 'service_account', | ||
| 'project_id': pod.getPassword('firebaseProjectId')!, | ||
| 'private_key_id': pod.getPassword('firebasePrivateKeyId')!, | ||
| 'private_key': pod.getPassword('firebasePrivateKey')!, | ||
| 'client_email': pod.getPassword('firebaseClientEmail')!, | ||
| 'client_id': pod.getPassword('firebaseClientId')!, | ||
| 'auth_uri': 'https://accounts.google.com/o/oauth2/auth', | ||
| 'token_uri': 'https://oauth2.googleapis.com/token', | ||
| }), | ||
| ); | ||
| ``` | ||
|
|
||
| :::warning | ||
| Do not inline the service account fields (especially `private_key`) directly in source code. Load every sensitive field from a secure source such as `pod.getPassword()` (backed by `passwords.yaml` or `SERVERPOD_PASSWORD_*` environment variables) or a secrets manager. | ||
| ::: | ||
|
|
||
| **Project ID only** (only token verification, no admin operations like deleting Firebase accounts): | ||
|
|
||
| ```dart | ||
| final firebaseIdpConfig = FirebaseIdpConfig( | ||
| credentials: const FirebaseServiceAccountCredentials( | ||
| projectId: 'your-project-id', | ||
| ), | ||
| ); | ||
| ``` | ||
|
|
||
| :::note | ||
| Only `projectId` is required to verify Firebase ID tokens. The full service account JSON is only needed if you also use the [admin operations](./admin-operations) on the server. | ||
| ::: | ||
|
|
||
| ## Custom account validation | ||
|
|
||
| You can customize the validation for Firebase account details before allowing sign-in. By default, the validation requires the email to be verified when present (phone-only authentication is allowed without an email). | ||
|
|
||
| To customize validation, provide your own `firebaseAccountDetailsValidation` function: | ||
|
|
||
| ```dart | ||
| final firebaseIdpConfig = FirebaseIdpConfigFromPasswords( | ||
| firebaseAccountDetailsValidation: (accountDetails) { | ||
| // Require verified email (even for phone auth) | ||
| if (accountDetails.verifiedEmail != true) { | ||
| throw Exception('Email must be verified'); | ||
| } | ||
|
|
||
| // Restrict to specific email domain | ||
| if (accountDetails.email != null && | ||
| !accountDetails.email!.endsWith('@example.com')) { | ||
| throw Exception('Only @example.com emails allowed'); | ||
| } | ||
| }, | ||
| ); | ||
| ``` | ||
|
|
||
| ### FirebaseAccountDetails properties | ||
|
|
||
| The `firebaseAccountDetailsValidation` callback receives a `FirebaseAccountDetails` record with the following properties: | ||
|
|
||
| - `userIdentifier` (`String`): Firebase UID. | ||
| - `email` (`String?`): Email address, or `null` for phone-only sign-in. | ||
| - `fullName` (`String?`): Display name from Firebase. | ||
| - `image` (`Uri?`): Profile image URL. | ||
| - `verifiedEmail` (`bool?`): Whether the email is verified. | ||
| - `phone` (`String?`): Phone number, only populated for phone authentication. | ||
|
|
||
| Which properties are populated depends on the Firebase sign-in method the user chose. For example, `phone` is only populated for phone authentication, and `email` may be `null` if the user signed in with phone only. | ||
|
|
||
| ## Reacting to auth user creation | ||
|
|
||
| [`onBeforeAuthUserCreated`](https://pub.dev/documentation/serverpod_auth_idp_server/latest/core/AuthUsersConfig/onBeforeAuthUserCreated.html) and [`onAfterAuthUserCreated`](https://pub.dev/documentation/serverpod_auth_idp_server/latest/core/AuthUsersConfig/onAfterAuthUserCreated.html) are global callbacks on `AuthUsersConfig`. They fire for every identity provider, not just Firebase. See [Working with users](../../working-with-users#reacting-to-the-user-created-event) for full details. | ||
|
|
||
| The example below uses Firebase phone numbers as the trigger for assigning a `phone-verified` scope at sign-up, and persists the Firebase UID for later admin lookups: | ||
|
|
||
| ```dart | ||
| pod.initializeAuthServices( | ||
| tokenManagerBuilders: [ | ||
| JwtConfigFromPasswords(), | ||
| ], | ||
| identityProviderBuilders: [ | ||
| FirebaseIdpConfigFromPasswords(), | ||
| ], | ||
| authUsersConfig: AuthUsersConfig( | ||
| onBeforeAuthUserCreated: ( | ||
| session, | ||
| scopes, | ||
| blocked, { | ||
| required transaction, | ||
| }) { | ||
| return ( | ||
| scopes: {...scopes, Scope('user')}, | ||
| blocked: blocked, | ||
| ); | ||
| }, | ||
| onAfterAuthUserCreated: ( | ||
| session, | ||
| authUser, { | ||
| required transaction, | ||
| }) async { | ||
| // e.g. send a welcome email, log for analytics | ||
| }, | ||
| ), | ||
| ); | ||
| ``` | ||
|
|
||
| :::warning | ||
| Both callbacks run inside the same database transaction as the account creation. Throwing an exception inside either callback aborts the sign-up. Wrap external side-effects (email sending, analytics) in `try`/`catch` so a third-party outage does not block new sign-ups. | ||
| ::: | ||
|
|
||
| ## FirebaseIdpConfig parameter reference | ||
|
|
||
| | Parameter | Type | Required | Description | | ||
| | --- | --- | --- | --- | | ||
| | `credentials` | `FirebaseServiceAccountCredentials` | Yes | Firebase service account credentials for verifying ID tokens. Can be loaded via `fromJsonString`, `fromJsonFile`, or `fromJson`. When using `FirebaseIdpConfigFromPasswords`, this is loaded automatically from the `firebaseServiceAccountKey` key in `passwords.yaml` or the `SERVERPOD_PASSWORD_firebaseServiceAccountKey` environment variable. | | ||
| | `firebaseAccountDetailsValidation` | `FirebaseAccountDetailsValidation?` | No | Custom validation callback for Firebase account details before allowing sign-in. By default, validates that email is verified when present (phone-only auth is allowed). | | ||
| | `onAfterFirebaseAccountCreated` | `AfterFirebaseAccountCreatedFunction?` | No | Callback invoked after a new Firebase account has been created and linked to an auth user. Receives the session, the created `AuthUserModel`, the `FirebaseAccount`, and the active `Transaction`. Runs inside the same database transaction as account creation, so the `transaction` can be used to perform additional database operations atomically with sign-up. | | ||
| | `clockSkewTolerance` | `Duration` | No | Tolerance for clock skew when validating Firebase ID token timestamps. Defaults to the framework's default clock skew tolerance. | |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.