Skip to content

feat(core)!: move the pure-Dart core types out of the Flutter platform interface - #18896

Draft
Lyokone wants to merge 4 commits into
mainfrom
feat/firebase-common
Draft

Lyokone wants to merge 4 commits into
mainfrom
feat/firebase-common

Conversation

@Lyokone

@Lyokone Lyokone commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Description

Dart web apps without Flutter (Jaspr, dart compile js/wasm) can't use FlutterFire web: firebase_core_platform_interface and firebase_core_web depend on Flutter, so dart pub get fails.

This moves the pure-Dart parts into three new packages:

  • firebase_common (top-level packages/firebase_common): FirebaseException, shared with the Dart server SDKs (Dart 3.9, meta only).
  • firebase_core_interface: FirebaseOptions, FirebasePlatform, FirebaseAppPlatform, FirebasePlugin and the core exceptions.
  • firebase_core_js: the JS SDK implementation, formerly in firebase_core_web. Dart apps register it with FirebaseCoreWeb.registerWith(); the registrar argument is now optional.

The platform interface and firebase_core_web re-export them, so app code doesn't change. firebase_core_web keeps only the Flutter registration (FirebaseCoreWebPlugin).

Breaking for plugin authors:

  • FirebaseOptions.fromPigeon is removed; use CoreFirebaseOptions.toFirebaseOptions().
  • On Android, Apple and Windows, reading FirebasePlatform.instance before any Firebase call or setupFirebaseCoreMocks() throws a StateError.

Release: the platform interface goes to 9.0.0, firebase_core and firebase_core_web get minors (melos -V), and the new packages publish at 1.0.0.

Tests

  • firebase_core/test/firebase_default_platform_test.dart: "Firebase uses MethodChannelFirebase when nothing registered" (fails without the fallback in Firebase).
  • firebase_core_interface/test/platform_interface_test.dart: the FirebasePlatform.instance fallback and FirebasePlugin constants.
  • firebase_core_platform_interface/test/pigeon_extensions_test.dart: "copies every field", "keeps optional fields null".
  • firebase_core_js/test/firebase_core_web_register_test.dart: "registerWith registers FirebaseCoreWeb without a registrar" (fails to compile without the fix).
  • firebase_core_web/test/firebase_core_web_plugin_test.dart: "registerWith registers FirebaseCoreWeb and the flutter-fire-core version".
  • New CI jobs: pure_dart_common tests firebase_common on Dart 3.9 without Flutter, and pure_dart_web builds a Dart-only web app to JS and Wasm.

Related Issues

None.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]).
This will ensure a smooth and quick review process. Updating the pubspec.yaml and changelogs is not required.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See Contributor Guide).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (melos run analyze) does not report any problems on my PR.
  • I read and followed the Flutter Style Guide.
  • I signed the CLA.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change.
  • No, this is not a breaking change.

…m interface

Dart web apps that do not use Flutter (Jaspr, `dart compile js`/`wasm`) can
now use Firebase Core with `dart pub get`: nothing they need depends on
Flutter any more.

- firebase_common (new, Dart ^3.9.0, depends only on meta): FirebaseException,
  the type the server Dart SDKs can share. Client contracts stay out of it,
  so their breaking changes never force a major here.
- firebase_core_interface (new): FirebasePlatform, FirebaseAppPlatform,
  FirebasePlugin, FirebaseOptions, defaultFirebaseAppName and the core
  exception helpers, moved from firebase_core_platform_interface.
- firebase_core_js (new): the web implementation (FirebaseCoreWeb), moved
  from firebase_core_web.
- firebase_core_platform_interface re-exports firebase_core_interface, and
  firebase_core_web re-exports firebase_core_js, so every symbol stays
  importable where it was, with the same type.
- firebase_core_web registers through FirebaseCoreWebPlugin, which assigns
  the platform interface's FirebasePlatform (an older platform interface
  then fails to compile instead of failing at runtime) and reports the
  flutter-fire-core version, also when the app loads the JS SDK itself. It
  depends on flutter_web_plugins again, so apps whose only web plugin is
  firebase_core build for web.
- firebase_core sets MethodChannelFirebase as the FirebasePlatform fallback
  on first use, since firebase_core_interface cannot reference it.
- CI: a pure_dart job tests firebase_common on Dart 3.9.0 and builds a
  non-Flutter web app on Dart 3.10.0; firebase_core_js tests run with
  `melos run test:js`.

BREAKING CHANGE: in firebase_core_platform_interface,
FirebaseOptions.fromPigeon is removed; use
CoreFirebaseOptions.toFirebaseOptions() instead. FirebasePlatform.instance
no longer defaults to MethodChannelFirebase by itself: read before any
Firebase call, it throws a StateError unless setupFirebaseCoreMocks() ran
or FirebasePlatform.fallbackInstanceFactory is set.

Release: version firebase_core_platform_interface as a major and
firebase_core and firebase_core_web as minors (melos -V), and publish
firebase_common, firebase_core_interface and firebase_core_js at 1.0.0, so
that dependents' constraints move to the new major and no mix of old and
new packages resolves.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request restructures the Firebase Core packages to extract pure-Dart types, contracts, and web implementations into three new Flutter-free packages: firebase_common, firebase_core_interface, and firebase_core_js. This separation allows non-Flutter Dart web applications to use Firebase Core without pulling in Flutter dependencies. The existing firebase_core_platform_interface and firebase_core_web packages have been updated to re-export and build upon these new packages. Feedback on the changes highlights a critical issue in firebase_core_web/pubspec.yaml, where the dependency constraint for firebase_core_platform_interface needs to be updated to ^9.0.0 to match its major version bump and ensure proper package resolution.

# `firebase_core` reads. The release that re-exports `firebase_core_interface`'s
# `FirebasePlatform` must be a major, so that this constraint excludes older
# versions, which define their own.
firebase_core_platform_interface: ^8.1.1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The dependency constraint for firebase_core_platform_interface is kept as ^8.1.1. However, as explained in the comment above and the PR description, the new version of firebase_core_platform_interface that re-exports firebase_core_interface is a major bump (9.0.0). Keeping ^8.1.1 will exclude 9.0.0 and prevent the packages from resolving together, or bind firebase_core_web to the old version of the platform interface which doesn't have the new exports. It must be updated to ^9.0.0.

  firebase_core_platform_interface: ^9.0.0

A second setup-dart in the same job fails because the first one's SDK download is still in RUNNER_TEMP.
It is shared with the Dart server SDKs, not specific to firebase_core, so it sits next to _flutterfire_internals. CI path filters, the analyze allowlist and the standalone checks point at the new location, and the package keeps firebase_core's avoid_dynamic_calls lint.
Dart web apps without Flutter can call FirebaseCoreWeb.registerWith() instead of passing null.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant