From d91122422b4fc4c9677a6ba2c1c779c04620f490 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Wed, 29 Apr 2026 22:04:14 -0700 Subject: [PATCH 01/10] Add appCheck registration --- .../firebase_ai/lib/src/firebase_ai.dart | 2 ++ .../test/firebase_vertexai_test.dart | 7 +++++++ .../lib/src/firebase_app_check.dart | 4 +++- .../firebase_core/lib/src/firebase_app.dart | 17 +++++++++++++++++ .../firebase_core/test/firebase_core_test.dart | 10 ++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index 3d7b22023e15..bb690b7da16d 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -68,6 +68,7 @@ class FirebaseAI extends FirebasePluginPlatform { bool? useLimitedUseAppCheckTokens, }) { app ??= Firebase.app(); + appCheck ??= app.getService(); var instanceKey = '${app.name}::vertexai::$location'; if (_cachedInstances.containsKey(instanceKey)) { @@ -100,6 +101,7 @@ class FirebaseAI extends FirebasePluginPlatform { bool? useLimitedUseAppCheckTokens, }) { app ??= Firebase.app(); + appCheck ??= app.getService(); var instanceKey = '${app.name}::googleai'; if (_cachedInstances.containsKey(instanceKey)) { diff --git a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart index 71c347f24333..24c09b52ae45 100644 --- a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart +++ b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart @@ -96,6 +96,13 @@ void main() { expect(vertexAIAppCheck.useLimitedUseAppCheckTokens, true); }); + test('Instance creation with auto-injected AppCheck', () { + final vertexAI = FirebaseAI.vertexAI(app: customApp); + + expect(vertexAI.app, equals(customApp)); + expect(vertexAI.appCheck, equals(customAppCheck)); + }); + test('generativeModel creation with Grounding tools', () { final ai = FirebaseAI.googleAI(); diff --git a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart index 25a1845449e8..fe30eb168aa7 100644 --- a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart +++ b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart @@ -41,7 +41,9 @@ class FirebaseAppCheck extends FirebasePluginPlatform { /// Returns an instance using a specified [FirebaseApp]. static FirebaseAppCheck instanceFor({required FirebaseApp app}) { return _firebaseAppCheckInstances.putIfAbsent(app.name, () { - return FirebaseAppCheck._(app: app); + final instance = FirebaseAppCheck._(app: app); + app.registerService(instance); + return instance; }); } diff --git a/packages/firebase_core/firebase_core/lib/src/firebase_app.dart b/packages/firebase_core/firebase_core/lib/src/firebase_app.dart index 841255c8dd7f..9a5bd58b7538 100644 --- a/packages/firebase_core/firebase_core/lib/src/firebase_app.dart +++ b/packages/firebase_core/firebase_core/lib/src/firebase_app.dart @@ -71,4 +71,21 @@ class FirebaseApp { @override String toString() => '$FirebaseApp($name)'; + + static final Map> _registries = {}; + + /// Registers a service instance for this app. + void registerService(T service) { + final registry = _registries.putIfAbsent(name, () => {}); + registry[T] = service; + } + + /// Returns a registered service instance for this app. + T? getService() { + final registry = _registries[name]; + if (registry != null) { + return registry[T] as T?; + } + return null; + } } diff --git a/packages/firebase_core/firebase_core/test/firebase_core_test.dart b/packages/firebase_core/firebase_core/test/firebase_core_test.dart index 87e4abe4718b..e3e402dd832f 100755 --- a/packages/firebase_core/firebase_core/test/firebase_core_test.dart +++ b/packages/firebase_core/firebase_core/test/firebase_core_test.dart @@ -64,6 +64,16 @@ void main() { mock.app(testAppName), ]); }); + + test('.registerService() and .getService()', () { + FirebaseApp app = Firebase.app(testAppName); + + const testService = 'testServiceInstance'; + app.registerService(testService); + + expect(app.getService(), testService); + expect(app.getService(), isNull); + }); }); test('.initializeApp() with demoProjectId', () async { From a581e9e171604dcc791e91386ed9f45307111292 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Wed, 29 Apr 2026 22:17:25 -0700 Subject: [PATCH 02/10] Add auth registration --- .../firebase_ai/firebase_ai/lib/src/firebase_ai.dart | 2 ++ .../firebase_ai/test/firebase_vertexai_test.dart | 12 +++++++++++- .../firebase_auth/lib/src/firebase_auth.dart | 4 +++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index bb690b7da16d..c8d0df678eac 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -69,6 +69,7 @@ class FirebaseAI extends FirebasePluginPlatform { }) { app ??= Firebase.app(); appCheck ??= app.getService(); + auth ??= app.getService(); var instanceKey = '${app.name}::vertexai::$location'; if (_cachedInstances.containsKey(instanceKey)) { @@ -102,6 +103,7 @@ class FirebaseAI extends FirebasePluginPlatform { }) { app ??= Firebase.app(); appCheck ??= app.getService(); + auth ??= app.getService(); var instanceKey = '${app.name}::googleai'; if (_cachedInstances.containsKey(instanceKey)) { diff --git a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart index 24c09b52ae45..fe52b397a106 100644 --- a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart +++ b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart @@ -14,6 +14,7 @@ import 'package:firebase_ai/firebase_ai.dart'; import 'package:firebase_app_check/firebase_app_check.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -28,6 +29,7 @@ void main() { late FirebaseApp customApp; late FirebaseApp limitTokenApp; late FirebaseAppCheck customAppCheck; + late FirebaseAuth customAuth; late FirebaseAppCheck limitTokenAppCheck; group('FirebaseAI Tests', () { @@ -47,6 +49,7 @@ void main() { appCheck = FirebaseAppCheck.instance; customAppCheck = FirebaseAppCheck.instanceFor(app: customApp); limitTokenAppCheck = FirebaseAppCheck.instanceFor(app: limitTokenApp); + customAuth = FirebaseAuth.instanceFor(app: customApp); }); test('Singleton behavior', () { @@ -98,11 +101,18 @@ void main() { test('Instance creation with auto-injected AppCheck', () { final vertexAI = FirebaseAI.vertexAI(app: customApp); - + expect(vertexAI.app, equals(customApp)); expect(vertexAI.appCheck, equals(customAppCheck)); }); + test('Instance creation with auto-injected Auth', () { + final vertexAI = FirebaseAI.vertexAI(app: customApp); + + expect(vertexAI.app, equals(customApp)); + expect(vertexAI.auth, equals(customAuth)); + }); + test('generativeModel creation with Grounding tools', () { final ai = FirebaseAI.googleAI(); diff --git a/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart b/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart index 6906c839d281..07d46169d46e 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart @@ -45,7 +45,9 @@ class FirebaseAuth extends FirebasePluginPlatform { required FirebaseApp app, }) { return _firebaseAuthInstances.putIfAbsent(app.name, () { - return FirebaseAuth._(app: app); + final instance = FirebaseAuth._(app: app); + app.registerService(instance); + return instance; }); } From 470ffe17618413556f48d51feca8ef2d86d1c245 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Wed, 29 Apr 2026 22:41:00 -0700 Subject: [PATCH 03/10] update example for the change --- packages/firebase_ai/firebase_ai/example/lib/main.dart | 5 +++-- .../firebase_ai/firebase_ai/example/lib/pages/chat_page.dart | 4 ++-- .../firebase_ai/example/lib/pages/function_calling_page.dart | 4 ++-- .../firebase_ai/example/lib/pages/grounding_page.dart | 4 ++-- .../firebase_ai/example/lib/pages/image_generation_page.dart | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/example/lib/main.dart b/packages/firebase_ai/firebase_ai/example/lib/main.dart index bb42d139229c..e4ecade7e468 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/main.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/main.dart @@ -13,6 +13,7 @@ // limitations under the License. import 'package:firebase_ai/firebase_ai.dart'; +import 'package:firebase_app_check/firebase_app_check.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; @@ -70,10 +71,10 @@ class _GenerativeAISampleState extends State { void _initializeModel(bool useVertexBackend) { if (useVertexBackend) { - final vertexInstance = FirebaseAI.vertexAI(auth: FirebaseAuth.instance); + final vertexInstance = FirebaseAI.vertexAI(); _currentModel = vertexInstance.generativeModel(model: 'gemini-2.5-flash'); } else { - final googleAI = FirebaseAI.googleAI(auth: FirebaseAuth.instance); + final googleAI = FirebaseAI.googleAI(); _currentModel = googleAI.generativeModel(model: 'gemini-2.5-flash'); } } diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart index 8a98241001d4..2b06bf7ba43c 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart @@ -57,12 +57,12 @@ class _ChatPageState extends State { : null, ); if (widget.useVertexBackend) { - _model = FirebaseAI.vertexAI(auth: FirebaseAuth.instance).generativeModel( + _model = FirebaseAI.vertexAI().generativeModel( model: 'gemini-2.5-flash', generationConfig: generationConfig, ); } else { - _model = FirebaseAI.googleAI(auth: FirebaseAuth.instance).generativeModel( + _model = FirebaseAI.googleAI().generativeModel( model: 'gemini-2.5-flash', generationConfig: generationConfig, ); diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart index ccd09c3e1b34..acd47f267018 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart @@ -236,8 +236,8 @@ class _FunctionCallingPageState extends State { ); final aiClient = widget.useVertexBackend - ? FirebaseAI.vertexAI(auth: FirebaseAuth.instance) - : FirebaseAI.googleAI(auth: FirebaseAuth.instance); + ? FirebaseAI.vertexAI() + : FirebaseAI.googleAI(); _functionCallModel = aiClient.generativeModel( model: 'gemini-2.5-flash', diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart index 8456be1a9e4c..b3ecbf93a53e 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart @@ -75,8 +75,8 @@ class _GroundingPageState extends State { } final aiProvider = widget.useVertexBackend - ? FirebaseAI.vertexAI(auth: FirebaseAuth.instance) - : FirebaseAI.googleAI(auth: FirebaseAuth.instance); + ? FirebaseAI.vertexAI() + : FirebaseAI.googleAI(); _model = aiProvider.generativeModel( model: 'gemini-2.5-flash', diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart index f4e2f527d3c4..22429139e412 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart @@ -48,8 +48,8 @@ class _ImageGenerationPageState extends State { void _initializeModel() { final aiClient = widget.useVertexBackend - ? FirebaseAI.vertexAI(auth: FirebaseAuth.instance) - : FirebaseAI.googleAI(auth: FirebaseAuth.instance); + ? FirebaseAI.vertexAI() + : FirebaseAI.googleAI(); _model = aiClient.generativeModel( model: 'gemini-2.5-flash-image', From 8017929170d1b19aeedd1c1d58ad04d237d29df8 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 10:58:06 -0700 Subject: [PATCH 04/10] clean up registries in app delete --- packages/firebase_core/firebase_core/lib/src/firebase_app.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/firebase_core/firebase_core/lib/src/firebase_app.dart b/packages/firebase_core/firebase_core/lib/src/firebase_app.dart index 9a5bd58b7538..e2b1758ad0b1 100644 --- a/packages/firebase_core/firebase_core/lib/src/firebase_app.dart +++ b/packages/firebase_core/firebase_core/lib/src/firebase_app.dart @@ -28,6 +28,7 @@ class FirebaseApp { /// Deleting the default app is not possible and throws an exception. Future delete() async { await _delegate.delete(); + _registries.remove(name); } /// The name of this [FirebaseApp]. From 9bf7cf9746b8ee6574a9a93a725b6672e7c49f29 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 10:59:59 -0700 Subject: [PATCH 05/10] fix analyzer --- packages/firebase_ai/firebase_ai/example/lib/main.dart | 2 +- .../firebase_ai/firebase_ai/example/lib/pages/chat_page.dart | 2 +- .../firebase_ai/example/lib/pages/function_calling_page.dart | 2 +- .../firebase_ai/example/lib/pages/grounding_page.dart | 2 +- .../firebase_ai/example/lib/pages/image_generation_page.dart | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/example/lib/main.dart b/packages/firebase_ai/firebase_ai/example/lib/main.dart index e4ecade7e468..b91bbd282276 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/main.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/main.dart @@ -13,7 +13,7 @@ // limitations under the License. import 'package:firebase_ai/firebase_ai.dart'; -import 'package:firebase_app_check/firebase_app_check.dart'; + import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart index 2b06bf7ba43c..bc8f119977a0 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:firebase_auth/firebase_auth.dart'; + import 'package:flutter/material.dart'; import 'package:firebase_ai/firebase_ai.dart'; import '../widgets/message_widget.dart'; diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart index acd47f267018..773a32b99926 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart @@ -14,7 +14,7 @@ import 'package:flutter/material.dart'; import 'package:firebase_ai/firebase_ai.dart'; -import 'package:firebase_auth/firebase_auth.dart'; + import '../utils/function_call_utils.dart'; import '../widgets/message_widget.dart'; diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart index b3ecbf93a53e..0e362fffa470 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:firebase_auth/firebase_auth.dart'; + import 'package:flutter/material.dart'; import 'package:firebase_ai/firebase_ai.dart'; import '../widgets/message_widget.dart'; diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart index 22429139e412..3d1112a424dc 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart @@ -15,7 +15,7 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:firebase_ai/firebase_ai.dart'; -import 'package:firebase_auth/firebase_auth.dart'; + import '../widgets/message_widget.dart'; class ImageGenerationPage extends StatefulWidget { From 4f3d9e2bba1e57947a7529b08e076913b548ec60 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 11:02:51 -0700 Subject: [PATCH 06/10] fix format --- .../firebase_ai/example/lib/pages/chat_page.dart | 1 - .../example/lib/pages/function_calling_page.dart | 5 ++--- .../firebase_ai/example/lib/pages/grounding_page.dart | 6 ++---- .../example/lib/pages/image_generation_page.dart | 5 ++--- .../firebase_core/test/firebase_core_test.dart | 4 ++-- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart index bc8f119977a0..24a29b59569f 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - import 'package:flutter/material.dart'; import 'package:firebase_ai/firebase_ai.dart'; import '../widgets/message_widget.dart'; diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart index 773a32b99926..64c5b39ad9b4 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart @@ -235,9 +235,8 @@ class _FunctionCallingPageState extends State { : null, ); - final aiClient = widget.useVertexBackend - ? FirebaseAI.vertexAI() - : FirebaseAI.googleAI(); + final aiClient = + widget.useVertexBackend ? FirebaseAI.vertexAI() : FirebaseAI.googleAI(); _functionCallModel = aiClient.generativeModel( model: 'gemini-2.5-flash', diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart index 0e362fffa470..e895e51c14cd 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - import 'package:flutter/material.dart'; import 'package:firebase_ai/firebase_ai.dart'; import '../widgets/message_widget.dart'; @@ -74,9 +73,8 @@ class _GroundingPageState extends State { } } - final aiProvider = widget.useVertexBackend - ? FirebaseAI.vertexAI() - : FirebaseAI.googleAI(); + final aiProvider = + widget.useVertexBackend ? FirebaseAI.vertexAI() : FirebaseAI.googleAI(); _model = aiProvider.generativeModel( model: 'gemini-2.5-flash', diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart index 3d1112a424dc..0b66b1e7f6d3 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart @@ -47,9 +47,8 @@ class _ImageGenerationPageState extends State { } void _initializeModel() { - final aiClient = widget.useVertexBackend - ? FirebaseAI.vertexAI() - : FirebaseAI.googleAI(); + final aiClient = + widget.useVertexBackend ? FirebaseAI.vertexAI() : FirebaseAI.googleAI(); _model = aiClient.generativeModel( model: 'gemini-2.5-flash-image', diff --git a/packages/firebase_core/firebase_core/test/firebase_core_test.dart b/packages/firebase_core/firebase_core/test/firebase_core_test.dart index e3e402dd832f..26608952b0b3 100755 --- a/packages/firebase_core/firebase_core/test/firebase_core_test.dart +++ b/packages/firebase_core/firebase_core/test/firebase_core_test.dart @@ -67,10 +67,10 @@ void main() { test('.registerService() and .getService()', () { FirebaseApp app = Firebase.app(testAppName); - + const testService = 'testServiceInstance'; app.registerService(testService); - + expect(app.getService(), testService); expect(app.getService(), isNull); }); From 4d6f70530f4f3de307dab1e1770392899aa32839 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 12:03:03 -0700 Subject: [PATCH 07/10] restrict the registry only for firebase service --- .../lib/src/firebase_app_check.dart | 2 +- .../firebase_auth/lib/src/firebase_auth.dart | 2 +- .../firebase_core/lib/src/firebase_app.dart | 7 +++++-- .../firebase_core/test/firebase_core_test.dart | 13 +++++++------ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart index fe30eb168aa7..0da4f3b5b1ce 100644 --- a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart +++ b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart @@ -5,7 +5,7 @@ part of '../firebase_app_check.dart'; -class FirebaseAppCheck extends FirebasePluginPlatform { +class FirebaseAppCheck extends FirebasePluginPlatform implements FirebaseService { static Map _firebaseAppCheckInstances = {}; FirebaseAppCheck._({required this.app}) diff --git a/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart b/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart index 07d46169d46e..f4fec1522d59 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart @@ -6,7 +6,7 @@ part of '../firebase_auth.dart'; /// The entry point of the Firebase Authentication SDK. -class FirebaseAuth extends FirebasePluginPlatform { +class FirebaseAuth extends FirebasePluginPlatform implements FirebaseService { // Cached instances of [FirebaseAuth]. static Map _firebaseAuthInstances = {}; diff --git a/packages/firebase_core/firebase_core/lib/src/firebase_app.dart b/packages/firebase_core/firebase_core/lib/src/firebase_app.dart index e2b1758ad0b1..b083f65c8118 100644 --- a/packages/firebase_core/firebase_core/lib/src/firebase_app.dart +++ b/packages/firebase_core/firebase_core/lib/src/firebase_app.dart @@ -76,13 +76,13 @@ class FirebaseApp { static final Map> _registries = {}; /// Registers a service instance for this app. - void registerService(T service) { + void registerService(T service) { final registry = _registries.putIfAbsent(name, () => {}); registry[T] = service; } /// Returns a registered service instance for this app. - T? getService() { + T? getService() { final registry = _registries[name]; if (registry != null) { return registry[T] as T?; @@ -90,3 +90,6 @@ class FirebaseApp { return null; } } + +/// A marker interface for Firebase services that can be registered in [FirebaseApp]. +abstract class FirebaseService {} diff --git a/packages/firebase_core/firebase_core/test/firebase_core_test.dart b/packages/firebase_core/firebase_core/test/firebase_core_test.dart index 26608952b0b3..9dc925fe8256 100755 --- a/packages/firebase_core/firebase_core/test/firebase_core_test.dart +++ b/packages/firebase_core/firebase_core/test/firebase_core_test.dart @@ -67,12 +67,11 @@ void main() { test('.registerService() and .getService()', () { FirebaseApp app = Firebase.app(testAppName); - - const testService = 'testServiceInstance'; - app.registerService(testService); - - expect(app.getService(), testService); - expect(app.getService(), isNull); + + final testService = TestService(); + app.registerService(testService); + + expect(app.getService(), testService); }); }); @@ -162,3 +161,5 @@ class MockFirebaseCore extends Mock // ignore: avoid_implementing_value_types class FakeFirebaseAppPlatform extends Fake implements FirebaseAppPlatform {} + +class TestService implements FirebaseService {} From da6951524999911a17eae7c27a619b7f7270b8e2 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 13:12:57 -0700 Subject: [PATCH 08/10] add deprecation message --- packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart | 8 ++++++++ .../firebase_app_check/lib/src/firebase_app_check.dart | 3 ++- .../firebase_core/test/firebase_core_test.dart | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index c8d0df678eac..40971c347362 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -62,7 +62,11 @@ class FirebaseAI extends FirebasePluginPlatform { /// If pass in [appCheck], request session will get protected from abusing. static FirebaseAI vertexAI({ FirebaseApp? app, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.') FirebaseAppCheck? appCheck, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.') FirebaseAuth? auth, String? location, bool? useLimitedUseAppCheckTokens, @@ -97,7 +101,11 @@ class FirebaseAI extends FirebasePluginPlatform { /// If pass in [appCheck], request session will get protected from abusing. static FirebaseAI googleAI({ FirebaseApp? app, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.') FirebaseAppCheck? appCheck, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.') FirebaseAuth? auth, bool? useLimitedUseAppCheckTokens, }) { diff --git a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart index 0da4f3b5b1ce..ba48413dbddd 100644 --- a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart +++ b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart @@ -5,7 +5,8 @@ part of '../firebase_app_check.dart'; -class FirebaseAppCheck extends FirebasePluginPlatform implements FirebaseService { +class FirebaseAppCheck extends FirebasePluginPlatform + implements FirebaseService { static Map _firebaseAppCheckInstances = {}; FirebaseAppCheck._({required this.app}) diff --git a/packages/firebase_core/firebase_core/test/firebase_core_test.dart b/packages/firebase_core/firebase_core/test/firebase_core_test.dart index 9dc925fe8256..b0770caf23a4 100755 --- a/packages/firebase_core/firebase_core/test/firebase_core_test.dart +++ b/packages/firebase_core/firebase_core/test/firebase_core_test.dart @@ -67,10 +67,10 @@ void main() { test('.registerService() and .getService()', () { FirebaseApp app = Firebase.app(testAppName); - + final testService = TestService(); app.registerService(testService); - + expect(app.getService(), testService); }); }); From 76d30dcdc6e91ea8908b6125e4dcd706a3a74646 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 13:25:37 -0700 Subject: [PATCH 09/10] make sure we still can have valid instance if auth and appCheck initialized after firebaseai init and before api call --- .../firebase_ai/lib/src/base_model.dart | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart index edd5a9a7c7b2..68184bebee7b 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart @@ -282,19 +282,23 @@ abstract class BaseModel { ) { return () async { Map headers = {}; + + final effectiveAppCheck = appCheck ?? app?.getService(); + final effectiveAuth = auth ?? app?.getService(); + // Override the client name in Google AI SDK headers['x-goog-api-client'] = 'gl-dart/$packageVersion fire/$packageVersion'; - if (appCheck != null) { + if (effectiveAppCheck != null) { final appCheckToken = useLimitedUseAppCheckTokens == true - ? await appCheck.getLimitedUseToken() - : await appCheck.getToken(); + ? await effectiveAppCheck.getLimitedUseToken() + : await effectiveAppCheck.getToken(); if (appCheckToken != null) { headers['X-Firebase-AppCheck'] = appCheckToken; } } - if (auth != null) { - final idToken = await auth.currentUser?.getIdToken(); + if (effectiveAuth != null) { + final idToken = await effectiveAuth.currentUser?.getIdToken(); if (idToken != null) { headers['Authorization'] = 'Firebase $idToken'; } From 1dcaf77554954cd4a3367bca4aee2c4b83f486a2 Mon Sep 17 00:00:00 2001 From: Cynthia J Date: Thu, 30 Apr 2026 17:25:39 -0700 Subject: [PATCH 10/10] format --- packages/firebase_ai/firebase_ai/lib/src/base_model.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart index 68184bebee7b..de9e8072d249 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart @@ -282,10 +282,10 @@ abstract class BaseModel { ) { return () async { Map headers = {}; - + final effectiveAppCheck = appCheck ?? app?.getService(); final effectiveAuth = auth ?? app?.getService(); - + // Override the client name in Google AI SDK headers['x-goog-api-client'] = 'gl-dart/$packageVersion fire/$packageVersion';