Visitar URL original
fix(core, web): keep App Check registered for secondary Firebase apps… · firebase/flutterfire@1345dbb · GitHub
Skip to content

Commit 1345dbb

Browse files
authored
fix(core, web): keep App Check registered for secondary Firebase apps (#18557)
* fix(core, web): keep App Check registered for secondary Firebase apps The #11625 startup path removed app-check from the service registry after the first initializeApp, so named apps never reactivated App Check before Auth on reload. * style(core, web): format App Check service initialization chain
1 parent 5283f14 commit 1345dbb

2 files changed

Lines changed: 86 additions & 6 deletions

File tree

‎packages/firebase_core/firebase_core_web/lib/src/firebase_core_web.dart‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ class FirebaseCoreWeb extends FirebasePlatform {
5757
);
5858
}
5959

60+
/// Whether [service] is still registered for per-app initialization.
61+
///
62+
/// Used by tests to ensure App Check is not removed after the first
63+
/// [initializeApp] (secondary apps must re-run ensurePluginInitialized).
64+
@visibleForTesting
65+
static bool isServiceRegistered(String service) =>
66+
_services.containsKey(service);
67+
6068
static const String _libraryName = 'flutter-fire-core';
6169

6270
/// Registers that [FirebaseCoreWeb] is the platform implementation.
@@ -399,15 +407,20 @@ class FirebaseCoreWeb extends FirebasePlatform {
399407
}
400408
}
401409

402-
final appCheck = _services.remove('app-check');
403-
if (appCheck != null) {
404-
// Activate app check first
405-
await appCheck.ensurePluginInitialized!(app!);
410+
// Activate App Check before other services so Auth/etc. attach tokens.
411+
// Do NOT remove 'app-check' from [_services]: secondary (named) apps also
412+
// need ensurePluginInitialized on each Firebase.initializeApp() call.
413+
// Removing it caused App Check to skip reactivation for named apps on
414+
// reload, so accounts:lookup ran without X-Firebase-AppCheck (#18556).
415+
final appCheck = _services['app-check'];
416+
final appCheckEnsureInitialized = appCheck?.ensurePluginInitialized;
417+
if (appCheckEnsureInitialized != null) {
418+
await appCheckEnsureInitialized(app!);
406419
}
407420

408421
await Future.wait(
409-
_services.values.map((service) {
410-
final ensureInitializedFunction = service.ensurePluginInitialized;
422+
_services.entries.where((entry) => entry.key != 'app-check').map((entry) {
423+
final ensureInitializedFunction = entry.value.ensurePluginInitialized;
411424

412425
if (ensureInitializedFunction == null || app == null) {
413426
return Future.value();
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2026 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
@TestOn('browser')
6+
library;
7+
8+
import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
9+
import 'package:firebase_core_web/firebase_core_web.dart';
10+
import 'package:flutter_test/flutter_test.dart';
11+
12+
void main() {
13+
group('App Check multi-app initialization', () {
14+
setUp(() async {
15+
FirebasePlatform.instance = FirebaseCoreWeb();
16+
});
17+
18+
test(
19+
'keeps app-check registered and re-runs ensurePluginInitialized for named apps',
20+
() async {
21+
final initializedAppNames = <String>[];
22+
23+
FirebaseCoreWeb.registerService(
24+
'app-check',
25+
productNameOverride: 'app_check',
26+
ensurePluginInitialized: (firebaseApp) async {
27+
initializedAppNames.add(firebaseApp.name);
28+
},
29+
);
30+
31+
expect(FirebaseCoreWeb.isServiceRegistered('app-check'), isTrue);
32+
33+
const options = FirebaseOptions(
34+
apiKey: 'fake-api-key',
35+
appId: '1:1234567890:web:fake',
36+
messagingSenderId: '1234567890',
37+
projectId: 'fake-project',
38+
authDomain: 'fake-project.firebaseapp.com',
39+
);
40+
41+
final coreWeb = FirebaseCoreWeb();
42+
final version = coreWeb.firebaseSDKVersion;
43+
await coreWeb.injectSrcScript(
44+
'https://www.gstatic.com/firebasejs/$version/firebase-app.js',
45+
'firebase_core',
46+
);
47+
48+
await FirebasePlatform.instance.initializeApp(options: options);
49+
50+
// Must still be registered so a secondary app can reactivate App Check.
51+
expect(FirebaseCoreWeb.isServiceRegistered('app-check'), isTrue);
52+
expect(initializedAppNames, contains('[DEFAULT]'));
53+
54+
await FirebasePlatform.instance.initializeApp(
55+
name: 'prod',
56+
options: options,
57+
);
58+
59+
expect(FirebaseCoreWeb.isServiceRegistered('app-check'), isTrue);
60+
expect(
61+
initializedAppNames,
62+
containsAll(['[DEFAULT]', 'prod']),
63+
);
64+
},
65+
);
66+
});
67+
}

0 commit comments

Comments
 (0)