Visitar URL original
fix(core, web): load firebase-app.js before component bundles to avoi… · firebase/flutterfire@4b731ae · GitHub
Skip to content

Commit 4b731ae

Browse files
fix(core, web): load firebase-app.js before component bundles to avoid WebKit import race (#18443)
1 parent 5d2d5bf commit 4b731ae

1 file changed

Lines changed: 37 additions & 18 deletions

File tree

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

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -208,28 +208,47 @@ class FirebaseCoreWeb extends FirebasePlatform {
208208
String version = firebaseSDKVersion;
209209
List<String> ignored = _ignoredServiceScripts;
210210

211-
await Future.wait(
212-
_services.values.map((service) {
213-
if (ignored.contains(service.override ?? service.name)) {
214-
return Future.value();
215-
}
216-
217-
const firestoreServiceName = 'firestore';
211+
Future<void> injectService(FirebaseWebService service) {
212+
if (ignored.contains(service.override ?? service.name)) {
213+
return Future.value();
214+
}
218215

219-
if (service.name == firestoreServiceName) {
220-
// Inject the Firestore Pipelines script. This bundle supports both
221-
// Pipeline operations (Enterprise edition) and standard Firestore queries.
222-
return injectSrcScript(
223-
'https://www.gstatic.com/firebasejs/$version/firebase-firestore-pipelines.js',
224-
'firebase_$firestoreServiceName',
225-
);
226-
}
216+
const firestoreServiceName = 'firestore';
227217

218+
if (service.name == firestoreServiceName) {
219+
// Inject the Firestore Pipelines script. This bundle supports both
220+
// Pipeline operations (Enterprise edition) and standard Firestore queries.
228221
return injectSrcScript(
229-
'https://www.gstatic.com/firebasejs/$version/firebase-${service.name}.js',
230-
'firebase_${service.override ?? service.name}',
222+
'https://www.gstatic.com/firebasejs/$version/firebase-firestore-pipelines.js',
223+
'firebase_$firestoreServiceName',
231224
);
232-
}),
225+
}
226+
227+
return injectSrcScript(
228+
'https://www.gstatic.com/firebasejs/$version/firebase-${service.name}.js',
229+
'firebase_${service.override ?? service.name}',
230+
);
231+
}
232+
233+
// Every component bundle (firebase-auth.js, firebase-messaging.js, ...)
234+
// statically imports from firebase-app.js. Loading all services with
235+
// concurrent dynamic import()s makes those imports race on the shared
236+
// firebase-app.js module, which trips a WebKit module-evaluation defect:
237+
// the returned namespace can still have its top-level bindings in the
238+
// temporal dead zone, so reading firebase.SDK_VERSION right afterwards
239+
// throws "ReferenceError: Cannot access 'SDK_VERSION' before
240+
// initialization" (Safari/WKWebView only). Load firebase-app.js first,
241+
// then fan out to the component bundles in parallel.
242+
// https://github.com/firebase/flutterfire/issues/18436
243+
final coreService = _services['core'];
244+
if (coreService != null) {
245+
await injectService(coreService);
246+
}
247+
248+
await Future.wait(
249+
_services.values
250+
.where((service) => !identical(service, coreService))
251+
.map(injectService),
233252
);
234253
registerLibraryVersion(_libraryName, packageVersion);
235254
_registerAllLibraryVersions();

0 commit comments

Comments
 (0)