Skip to content

feat(core)!: extract Flutter free types into firebase_core_common - #18788

Closed
cedvdb wants to merge 3 commits into
firebase:mainfrom
cedvdb:feat/pure-dart-core-leaf-v2
Closed

cedvdb wants to merge 3 commits into
firebase:mainfrom
cedvdb:feat/pure-dart-core-leaf-v2

Conversation

@cedvdb

@cedvdb cedvdb commented Oct 13, 2026 •

Copy link
Copy Markdown

Description

Move the Flutter independent types into a new firebase_core_common package which the platform interface depends on and re-exports, so that a single class identity is kept for every consumer.


Breaking change: firebase_core_common does not depend on the Flutter dependent Pigeon models: Pigeon's output stays untouched, and the conversion of the Pigeon options model into FirebaseOptions - which used to be the FirebaseOptions.fromPigeon constructor - moves to firebaseOptionsFromPigeon in firebase_core_platform_interface, next to the MethodChannel implementation which is its only user.

An alternative would have been to move the flutter independent models, after generation. This avoid a breaking change, but in this case i believe the breaking change is niche (fromPigeon), not worth the complexity cost of splitting the output after gen.

Before merging this I believe that strategy should be investigated accros other packages, to see whether the breaking change or alternative is better suited (in particular in regards to firestore).


As the platform interface can no longer reference MethodChannelFirebase, FirebasePlatform.instance does not default to it anymore: implementations register themselves (FirebaseCoreWeb from registerWith), isRegistered allows to check it, and firebase_core installs the MethodChannel implementation lazily on the first usage of the Firebase API.

firebase_core_web now depends on firebase_core_common directly, so it can be used without a Flutter dependency. Neither package declares a flutter constraint in its environment anymore: pub does not select a package which declares one when Flutter is not available, so that constraint alone made both packages unreachable from pure Dart applications.

Part of #18645

Migration Guide

Replace FirebaseOptions.fromPigeon()

Before:

final options = FirebaseOptions.fromPigeon(response.options);

After:

final options = firebaseOptionsFromPigeon(response.options);

Register the platform implementation

Implementations of FirebasePlatform must install themselves (FirebasePlatform.instance = MyFirebasePlatform()) from their plugin's registerWith, as firebase_core (MethodChannelFirebase) and firebase_core_web (FirebaseCoreWeb) do.

Related Issues

#18645

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.

`firebase_core_platform_interface` could not be consumed outside of Flutter
because everything it exposed lived in a single library importing
`package:flutter/*`. Move the Flutter independent types (`FirebaseApp`,
`FirebaseAppPlatform`, `FirebaseOptions`, `FirebaseException`,
`FirebasePlatform`, `FirebasePlugin`, `defaultFirebaseAppName` and the shared
exception helpers) into a new `firebase_core_common` package which the platform
interface depends on and re-exports, so that a single class identity is kept for
every consumer.

`firebase_core_common` deliberately does not depend on the Flutter dependent
Pigeon models: Pigeon's output stays untouched, and the conversion of the Pigeon
options model into `FirebaseOptions` - which used to be the
`FirebaseOptions.fromPigeon` constructor - moves to `firebaseOptionsFromPigeon`
in `firebase_core_platform_interface`, next to the `MethodChannel`
implementation which is its only user.

As the platform interface can no longer reference `MethodChannelFirebase`,
`FirebasePlatform.instance` does not default to it anymore: implementations
register themselves (`FirebaseCoreWeb` from `registerWith`), `isRegistered`
allows to check it, and `firebase_core` installs the MethodChannel
implementation lazily on the first usage of the `Firebase` API.

`firebase_core_web` now depends on `firebase_core_common` directly, so it can
be used without a Flutter dependency. Neither package declares a `flutter`
constraint in its `environment` anymore: pub does not select a package which
declares one when Flutter is not available, so that constraint alone made both
packages unreachable from pure Dart applications. The Flutter version a
consumer needs is still enforced by `firebase_core` and
`firebase_core_platform_interface`. `melos run check:pure-dart` compiles a Dart
only entry point which uses `firebase_core_web`, so a Flutter library becoming
reachable from it fails the build.

The tests of `firebase_core_common` use `package:test` instead of
`flutter_test`, so the package does not depend on Flutter at all.

Part of firebase#18645

BREAKING CHANGE: `FirebaseOptions.fromPigeon` has been removed, because
`FirebaseOptions` now lives in the Flutter free `firebase_core_common`, which
must not depend on the Flutter dependent Pigeon models. Use the equivalent
`firebaseOptionsFromPigeon` function, exposed by
`firebase_core_platform_interface`, or build `FirebaseOptions` directly from the
fields of the Pigeon response. `FirebasePlatform.instance` also does not default
to `MethodChannelFirebase` anymore, so platform implementations must register
themselves before the `Firebase` API is used.

## Migration Guide

### Replace `FirebaseOptions.fromPigeon()`

**Before:**
```dart
final options = FirebaseOptions.fromPigeon(response.options);
```

**After:**
```dart
final options = firebaseOptionsFromPigeon(response.options);
```

### Register the platform implementation

Implementations of `FirebasePlatform` must install themselves
(`FirebasePlatform.instance = MyFirebasePlatform()`) from their plugin's
`registerWith`, as `firebase_core` (`MethodChannelFirebase`) and
`firebase_core_web` (`FirebaseCoreWeb`) do.
@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

@cedvdb

cedvdb commented Oct 13, 2026

Copy link
Copy Markdown
Author

/gemini review

@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 extracts pure Dart types and platform interfaces from firebase_core_platform_interface into a new package firebase_core_common, allowing Firebase Core platform implementations to be consumed outside of Flutter. Corresponding dependencies and imports have been updated across firebase_core, firebase_core_platform_interface, and firebase_core_web. Feedback on the changes includes a recommendation to make the constants parameter nullable in registerConstantsForApp to prevent potential runtime errors, and a suggestion to avoid using the ! operator in firebase.dart by utilizing flow analysis with a local variable, in compliance with the repository style guide.

Comment thread packages/firebase_core/firebase_core/lib/src/firebase.dart Outdated
cedvdb and others added 2 commits October 13, 2026 22:27
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…nterface/platform_interface_firebase_plugin.dart

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

@kevmoo kevmoo 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.

Please hold off on further changes here while we finish aligning with the maintainers on the broader #18645 design, which overlaps directly with this PR:

  1. Package name, location, and library split (package:firebase_common): Rather than a core-only firebase_core_common package, we are planning a single pure-Dart leaf package package:firebase_common (at packages/firebase_common) that also hosts shared Firestore value types (Timestamp, GeoPoint, VectorValue, Blob, FieldPath in package:firebase_common/firestore.dart) across flutterfire, firebase-admin-dart, and firebase-functions-dart. It also separates pure domain models (package:firebase_common/firebase_common.dart) from plugin_platform_interface contracts (package:firebase_common/platform_interface.dart) so server packages do not pull in plugin_platform_interface.
  2. Moving Firebase alongside FirebaseApp: cloud_firestore_web.dart and firebase_auth_web.dart take FirebaseApp and call Firebase.app(). Leaving Firebase in package:firebase_core still forces other *_web packages to depend on package:firebase_core (Flutter).
  3. Pigeon conversion & repo tooling: Prefer an extension (extension CoreFirebaseOptionsX on CoreFirebaseOptions { FirebaseOptions toFirebaseOptions() }) in firebase_core_platform_interface over a top-level firebaseOptionsFromPigeon function, add the direct dependency to firebase_core/pubspec.yaml, and update scripts/bom_analysis.dart and scripts/generate_bom.dart to tolerate workspace packages without an environment.flutter key.

Moving FirebaseApp into the pure-Dart package and lazily registering MethodChannelFirebase in Firebase._delegate are both directionally aligned with where we want to go—we'll follow up on #18645 and this PR once the package layout is locked down so you don't have to do throwaway rework.

@cedvdb

cedvdb commented Oct 20, 2026 •

Copy link
Copy Markdown
Author

I'm closing this for now. We ended up calling our flutter side app directly from the jaspr client once it is loaded instead.

@cedvdb cedvdb closed this Oct 20, 2026
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.

2 participants