-
Notifications
You must be signed in to change notification settings - Fork 59
refactor: initializeApp() with optional params, add multi-app support, service caching, and auto project ID discovery #106
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
Open
demolaf
wants to merge
18
commits into
next
Choose a base branch
from
feat/rework
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
4dbc07e
wip refactor FirebaseApp initialization logic
demolaf 4caa770
fix: incorrect metadata url
demolaf 2bd273a
feat: add getOrInitService to each service for caching and cleanup
demolaf bfd0b6b
fix: doc comments
demolaf 76cd71d
fix: tests errors
demolaf a5083aa
fix: tests errors, skip flaky tests
demolaf fad6978
fix: lint errors
demolaf 795d63b
fix: ensure emulator is running for e2e tests
demolaf ee092fe
add run scripts to example
demolaf 413fed8
fix: lint errors
demolaf 4385d1e
fix: lint errors
demolaf 489e44a
chore: cleanup main.dart, add comments to script on how to test example
demolaf b90a534
chore: better test description
demolaf e1de830
fix: services with emulator capabilities should use unauthenticated c…
demolaf 08a948c
refactor: All services now use FirebaseServiceType for registration, …
demolaf 9a75a26
feat: added convenience instance methods for each service
demolaf 5eb4816
fix: lint errors
demolaf c6bf15f
refactor: separate HTTP clients and request handlers
demolaf 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
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 |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ firebase.json | |
| .firebaserc | ||
| firestore.indexes.json | ||
| firestore.rules | ||
| serviceAccountKey.json | ||
|
|
||
| # Logs | ||
| logs | ||
|
|
||
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 |
|---|---|---|
| @@ -1,44 +1,62 @@ | ||
| import 'package:dart_firebase_admin/auth.dart'; | ||
| import 'package:dart_firebase_admin/dart_firebase_admin.dart'; | ||
| import 'package:dart_firebase_admin/firestore.dart'; | ||
| import 'package:dart_firebase_admin/messaging.dart'; | ||
|
|
||
| Future<void> main() async { | ||
| final admin = FirebaseAdminApp.initializeApp( | ||
| 'dart-firebase-admin', | ||
| Credential.fromApplicationDefaultCredentials(), | ||
| ); | ||
|
|
||
| // // admin.useEmulator(); | ||
| final admin = FirebaseApp.initializeApp(); | ||
| await authExample(admin); | ||
| await firestoreExample(admin); | ||
| await admin.close(); | ||
| } | ||
|
|
||
| final messaging = Messaging(admin); | ||
| Future<void> authExample(FirebaseApp admin) async { | ||
| print('\n### Auth Example ###\n'); | ||
|
|
||
| final auth = Auth(admin); | ||
|
|
||
| UserRecord? user; | ||
| try { | ||
| print('> Check if user with email exists: [email protected]\n'); | ||
| user = await auth.getUserByEmail('[email protected]'); | ||
| print('> User found by email\n'); | ||
| } on FirebaseAuthAdminException catch (e) { | ||
| if (e.errorCode == AuthClientErrorCode.userNotFound) { | ||
| print('> User not found, creating new user\n'); | ||
| user = await auth.createUser( | ||
| CreateRequest( | ||
| email: '[email protected]', | ||
| password: 'Test@123', | ||
| ), | ||
| ); | ||
| } else { | ||
| print('> Auth error: ${e.errorCode} - ${e.message}'); | ||
| } | ||
| } catch (e, stackTrace) { | ||
| print('> Unexpected error: $e'); | ||
| print('Stack trace: $stackTrace'); | ||
| } | ||
|
|
||
| final result = await messaging.send( | ||
| TokenMessage( | ||
| token: | ||
| 'e8Ap1n9UTQenyB-UEjNQt9:APA91bHhgc9RZYDcCKb7U1scQo1K0ZTSMItop8IqctrOcgvmN__oBo4vgbFX-ji4atr1PVw3Loug-eOCBmj4HVZjUE0aQBA0mGry7uL-7JuMaojhtl13MpvQtbZptvX_8f6vDcqei88O', | ||
| notification: Notification( | ||
| title: 'Hello', | ||
| body: 'World', | ||
| ), | ||
| ), | ||
| ); | ||
| if (user != null) { | ||
| print('Fetched user email: ${user.email}'); | ||
| } | ||
| } | ||
|
|
||
| print(result); | ||
| Future<void> firestoreExample(FirebaseApp admin) async { | ||
| print('\n### Firestore Example ###\n'); | ||
|
|
||
| final firestore = Firestore(admin); | ||
|
|
||
| final collection = firestore.collection('users'); | ||
|
|
||
| await collection.doc('123').set({ | ||
| 'name': 'John Doe', | ||
| 'age': 30, | ||
| }); | ||
|
|
||
| final snapshot = await collection.get(); | ||
|
|
||
| for (final doc in snapshot.docs) { | ||
| print(doc.data()); | ||
| try { | ||
| final collection = firestore.collection('users'); | ||
| await collection.doc('123').set({ | ||
| 'name': 'John Doe', | ||
| 'age': 27, | ||
| }); | ||
| final snapshot = await collection.get(); | ||
| for (final doc in snapshot.docs) { | ||
| print('> Document data: ${doc.data()}'); | ||
| } | ||
| } catch (e) { | ||
| print('> Error setting document: $e'); | ||
| } | ||
|
|
||
| await admin.close(); | ||
| } |
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,9 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Set environment variables for emulator | ||
| export FIRESTORE_EMULATOR_HOST=localhost:8080 | ||
| export FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 | ||
| export GOOGLE_CLOUD_PROJECT=dart-firebase-admin | ||
|
|
||
| # Run the example | ||
| dart run lib/main.dart |
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,35 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Run example against Firebase production | ||
| # | ||
| # Authentication Options: | ||
| # | ||
| # Option 1: Service Account Key (used by this script) | ||
| # 1. Download your service account key from Firebase Console: | ||
| # - Go to Project Settings > Service Accounts | ||
| # - Click "Generate New Private Key" | ||
| # - Save as serviceAccountKey.json in this directory | ||
| # 2. Set GOOGLE_APPLICATION_CREDENTIALS below (already configured) | ||
| # | ||
| # Option 2: Application Default Credentials (alternative) | ||
| # 1. Run: gcloud auth application-default login | ||
| # 2. Set GOOGLE_CLOUD_PROJECT or GCLOUD_PROJECT (uncomment below) | ||
| # 3. Comment out GOOGLE_APPLICATION_CREDENTIALS | ||
| # | ||
| # For available environment variables, see: | ||
| # ../lib/src/app/environment.dart | ||
|
|
||
| # Service account credentials file path | ||
| # See: Environment.googleApplicationCredentials | ||
| export GOOGLE_APPLICATION_CREDENTIALS=serviceAccountKey.json | ||
|
|
||
| # (Optional) Explicit project ID - uncomment if needed | ||
| # See: Environment.googleCloudProject | ||
| # export GOOGLE_CLOUD_PROJECT=your-project-id | ||
|
|
||
| # (Optional) Legacy gcloud project ID - uncomment if needed | ||
| # See: Environment.gcloudProject | ||
| # export GCLOUD_PROJECT=your-project-id | ||
|
|
||
| # Run the example | ||
| dart run lib/main.dart | ||
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 |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| export 'src/app_check/app_check.dart'; | ||
| export 'src/app_check/app_check.dart' | ||
| hide AppCheckRequestHandler, AppCheckHttpClient; | ||
| export 'src/app_check/app_check_api.dart'; |
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 |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export 'src/auth.dart' hide UserMetadataToJson; | ||
| export 'src/auth.dart' | ||
| hide UserMetadataToJson, AuthRequestHandler, AuthHttpClient; |
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 |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export 'src/app.dart' hide envSymbol; | ||
| export 'src/app.dart' | ||
| hide envSymbol, ApplicationDefaultCredential, ServiceAccountCredential; |
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 |
|---|---|---|
| @@ -1,2 +1,6 @@ | ||
| export 'src/google_cloud_firestore/firestore.dart' | ||
| hide $SettingsCopyWith, ApiMapValue; | ||
| hide | ||
| $SettingsCopyWith, | ||
| ApiMapValue, | ||
| AggregateFieldInternal, | ||
| FirestoreHttpClient; |
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 |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export 'src/messaging.dart' hide FirebaseMessagingRequestHandler; | ||
| export 'src/messaging/messaging.dart' | ||
| hide FirebaseMessagingRequestHandler, FirebaseMessagingHttpClient; |
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 |
|---|---|---|
| @@ -1,4 +1,2 @@ | ||
| export 'src/security_rules/security_rules.dart'; | ||
| export 'src/security_rules/security_rules_api_internals.dart' | ||
| hide SecurityRulesApiClient; | ||
| export 'src/security_rules/security_rules_internals.dart'; | ||
| export 'src/security_rules/security_rules.dart' | ||
| hide SecurityRulesRequestHandler, SecurityRulesHttpClient; |
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
107 changes: 107 additions & 0 deletions
107
packages/dart_firebase_admin/lib/src/app/app_exception.dart
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,107 @@ | ||
| part of '../app.dart'; | ||
|
|
||
| /// Exception thrown for Firebase app initialization and lifecycle errors. | ||
| class FirebaseAppException implements Exception { | ||
| FirebaseAppException( | ||
| this.errorCode, [ | ||
| String? message, | ||
| ]) : code = errorCode.code, | ||
| _message = message; | ||
|
|
||
| /// The error code object containing code and default message. | ||
| final AppErrorCode errorCode; | ||
|
|
||
| /// The error code string. | ||
| final String code; | ||
|
|
||
| /// Custom error message, if provided. | ||
| final String? _message; | ||
|
|
||
| /// The error message. Returns custom message if provided, otherwise default. | ||
| String get message => _message ?? errorCode.message; | ||
|
|
||
| @override | ||
| String toString() => 'FirebaseAppException($code): $message'; | ||
| } | ||
|
|
||
| /// Firebase App error codes with their default messages. | ||
| /// | ||
| /// These error codes match the Node.js SDK's AppErrorCodes for consistency. | ||
| enum AppErrorCode { | ||
| /// Firebase app with the given name has already been deleted. | ||
| appDeleted( | ||
| code: 'app-deleted', | ||
| message: 'The specified Firebase app has already been deleted.', | ||
| ), | ||
|
|
||
| /// Firebase app with the same name already exists. | ||
| duplicateApp( | ||
| code: 'duplicate-app', | ||
| message: 'A Firebase app with the given name already exists.', | ||
| ), | ||
|
|
||
| /// Invalid argument provided to a Firebase App method. | ||
| invalidArgument( | ||
| code: 'invalid-argument', | ||
| message: 'Invalid argument provided.', | ||
| ), | ||
|
|
||
| /// An internal error occurred within the Firebase SDK. | ||
| internalError( | ||
| code: 'internal-error', | ||
| message: 'An internal error has occurred.', | ||
| ), | ||
|
|
||
| /// Invalid Firebase app name provided. | ||
| invalidAppName( | ||
| code: 'invalid-app-name', | ||
| message: 'Invalid Firebase app name provided.', | ||
| ), | ||
|
|
||
| /// Invalid app options provided to initializeApp(). | ||
| invalidAppOptions( | ||
| code: 'invalid-app-options', | ||
| message: 'Invalid app options provided to initializeApp().', | ||
| ), | ||
|
|
||
| /// Invalid credential configuration. | ||
| invalidCredential( | ||
| code: 'invalid-credential', | ||
| message: 'The credential configuration is invalid.', | ||
| ), | ||
|
|
||
| /// Network error occurred during the operation. | ||
| networkError( | ||
| code: 'network-error', | ||
| message: 'A network error has occurred.', | ||
| ), | ||
|
|
||
| /// Network timeout occurred during the operation. | ||
| networkTimeout( | ||
| code: 'network-timeout', | ||
| message: 'The network request timed out.', | ||
| ), | ||
|
|
||
| /// No Firebase app exists with the given name. | ||
| noApp( | ||
| code: 'no-app', | ||
| message: 'No Firebase app exists with the given name.', | ||
| ), | ||
|
|
||
| /// Unable to parse the server response. | ||
| unableToParseResponse( | ||
| code: 'unable-to-parse-response', | ||
| message: 'Unable to parse the response from the server.', | ||
| ); | ||
|
|
||
| const AppErrorCode({ | ||
| required this.code, | ||
| required this.message, | ||
| }); | ||
|
|
||
| /// The error code string identifier. | ||
| final String code; | ||
|
|
||
| /// The default error message for this error code. | ||
| final String message; | ||
| } |
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.