Skip to content

firebase_app_check_tvos: regenerate Pigeon for 0.4.7 and drop the 0.4.6 pin - #26

Merged
MAUstaoglu merged 3 commits into
fluttertv:mainfrom
TheNoumanDev:fix/app-check-tvos-0.4.7
Sep 18, 2026
Merged

MAUstaoglu merged 3 commits into
fluttertv:mainfrom
TheNoumanDev:fix/app-check-tvos-0.4.7

Conversation

@TheNoumanDev

@TheNoumanDev TheNoumanDev commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Completes the follow-up left open on #25: firebase_app_check_tvos was pinned below 0.4.6 because that release moved the platform-interface Pigeon contract. #25 published firebase_core_tvos 0.0.3, which unblocks it.

What 0.4.6 changed

0.4.5 (pinned) 0.4.7 (now)
activate 4 args 5 — adds recaptchaSiteKey
getTokenResult absent present, returns InternalAppCheckTokenResult

The old generated Swift covered neither, so the pin was ">=0.4.5 <0.4.6".

Where the sources come from

firebase_app_check 0.4.7. FirebaseAppCheckMessages.g.swift is copied from it; the only delta against upstream is the import guard:

-#if os(iOS)
+#if (os(iOS) || os(tvOS))

getTokenResult in FirebaseAppCheckPlugin.swift is byte-identical to upstream's. activate and both configure() methods now carry recaptchaSiteKey, and the recaptcha case passes it to RecaptchaProvider(app:siteKey:) — still inside #if os(iOS), since reCAPTCHA is not a tvOS provider.

0.4.7's other Apple-side fix is carried over too: appAttestWithDeviceCheckFallback checks DCAppAttestService.shared.isSupported rather than the OS version alone, so the provider actually falls back (flutterfire#18568). import DeviceCheck is restored for it and the porter's tvOS 15.0 availability kept. Constants.swift moves to "0.4.7", and the README / PORTING_REPORT.md are re-synced off 0.4.5.

Why a closed window, not a caret

firebase_app_check: ">=0.4.7 <0.4.8", and the example pins exact.

This is the package that caused the rule: on #18 a ^0.4.5 silently admitted 0.4.6, which moved the Pigeon contract and produced a MissingPluginException plus a silently-dropped argument. ^0.4.7 would admit 0.4.8 the same way.

0.4.8 has since shipped. Its Apple sources are byte-identical to 0.4.7 apart from versionNumber, it declares the same firebase_app_check_platform_interface: ^0.4.2+1, and its only substantive change is bumping the Firebase iOS SDK to 12.19.0 — so the contract did not move and the generated Swift here already covers it. Widening to ">=0.4.7 <0.4.9" is therefore defensible (a closed window over a diffed version, not a caret over an unverified one), but left at <0.4.8 unless you prefer otherwise.

firebase_core_tvos is floored at ^0.0.3 here rather than the fleet's ^0.0.1. 0.4.7 requires firebase_core_platform_interface ^8.1.1: 0.0.2 excludes itself by declaring pi >=7.1.0 <8.1.0, but 0.0.1 declares no pi constraint at all, so the solver can legally pick it, and its native Pigeon expects the pre-8.1 FirebaseOptions payload — a crash at launch rather than a resolution error. The floor makes that a solver error instead. It costs nothing: this package cannot serve the 4.11.x train anyway.

Review #25, point 4

Six example pubspecs carried comments describing the 15-field payload as matching firebase_core_tvos's native Pigeon — true for 0.0.2, misleading once 0.0.3 is published. Each is replaced with two lines naming which firebase_core_tvos the firebase_core pin actually selects. Note ^0.0.1 was never an exact pin: in pub semantics it is >=0.0.1 <0.1.0, so it floats across 0.0.1–0.0.3 and the firebase_core pin is what resolves it. Versions are unchanged: every PORTING_REPORT names a specific upstream, so the exact pins are deliberate.

Only firebase_app_check_tvos has changes outside example/, so no other package needs a release.

Verified

$ python3 .github/scripts/check_repo.py .
Checked 25 package(s) under packages/
  OK — README rows, versions, required files, overrides and tvOS plugin classes all consistent.

$ dart analyze lib && dart analyze test   # No issues found!
$ flutter test                            # All tests passed!
$ flutter pub publish --dry-run           # Package has 0 warnings.

Payload arity, both ends:

Dart activate (interface 0.4.2+1) 5 elements
native activate 5 parameters
getTokenResult present both sides

All seven touched examples resolve and analyse clean. They do not all land on the same firebase_core_tvos: this package's example resolves 0.0.3, while the other six pin firebase_core: 4.11.0 and 0.0.3 requires firebase_core ^4.13.0, so they resolve 0.0.2 — correct for that train, and what the new comments say.

Simulator pass — Apple TV 4K (3rd generation), tvOS 26.5, native Firebase/AppCheck 12.15.0, live Firebase project:

Probe Result
activate(Debug) ok — 5-argument payload accepted
getToken reaches …/exchangeDebugToken, HTTP 403 (debug token not registered)
getLimitedUseToken same endpoint, same 403 — i.e. the channel dispatches
activate(DeviceCheck) ok; getToken → "DeviceCheckProvider is not supported…"
activate(AppAttestFallback) ok; getToken → "DeviceCheckProvider is not supported…"

All three activate() calls crossed the 5-argument payload with no codec error, no arity error and no MissingPluginException. Both token calls reached the App Check backend with the right project and app ID and returned typed FirebaseExceptions to Dart; the 403 is a console-registration gap, not a plugin defect.

The last row is the fallback fix working: the simulator reports tvOS 26.5, so the old #available(tvOS 15.0) check passed and selected App Attest — a control build with the pre-fix block reports "AppAttestProvider is not supported…" on the same call. The example gained an activate (Debug) and a getLimitedUseToken button so the sequence is reproducible by hand.

Release order

firebase_core_tvos 0.0.3 is already on pub.dev, so there is no blocking chain: this can publish as soon as it is merged.

@TheNoumanDev TheNoumanDev changed the title fix(firebase_core_tvos): regenerate Pigeon for the 14-element payload and drop the interface pin firebase_app_check_tvos: regenerate Pigeon for 0.4.7 and drop the 0.4.6 pin Sep 14, 2026
@TheNoumanDev

Copy link
Copy Markdown
Contributor Author

Hey @MAUstaoglu, can you please take a look at this follow-up PR and let me know if anything needs to change? Thanks

@MAUstaoglu MAUstaoglu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, the Pigeon regen and getTokenResult look right (checked against 0.4.7 from pub.dev). A few things from 0.4.7 are still missing though:

1. App Attest fallback fix not ported. 0.4.7 also fixed appAttestWithDeviceCheckFallback never actually falling back (flutterfire#18568). FirebaseAppCheckPlugin.swift still has the old block, so where App Attest isn't supported (e.g. tvOS simulator) it never switches to DeviceCheck. Please mirror upstream, keeping tvOS 15.0:

import DeviceCheck
...
case "appAttestWithDeviceCheckFallback":
  var appAttestProvider: (any AppCheckProvider)?
  if #available(iOS 14.0, tvOS 15.0, macOS 14.0, *), DCAppAttestService.shared.isSupported {
    appAttestProvider = AppAttestProvider(app: app)
  }
  delegateProvider = appAttestProvider ?? DeviceCheckProvider(app: app)

2. tvos/Classes/Constants.swift still has versionNumber = "0.4.5". Should be "0.4.7".

3. Docs still describe 0.4.5:

  • README.md: install snippet says firebase_app_check: ^0.4.5. Please use ">=0.4.7 <0.4.8" like the pubspec, and update the "ported from 0.4.5" header.
  • PORTING_REPORT.md: source/version-alignment sections (lines 5, 60–63) say 0.4.5 is the latest on the train.
  • The simulator "verified" row in the README was tested on 0.4.5. Either re-verify or mark it as not re-verified for 0.0.2.

4. New example comment is inaccurate. "Exact pins: firebase_core and firebase_core_tvos must move together", but firebase_core_tvos is ^0.0.1 everywhere. Something like # firebase_core is pinned exact; its train selects the matching firebase_core_tvos. would be accurate.

5. Simulator check before merge: run the example and confirm activate()getToken() / getLimitedUseToken() round-trips with the new 5-arg payload.

Minor, optional: in the package pubspec firebase_core_tvos: ^0.0.3 states the real floor, since 0.4.7 can only resolve 0.0.3 anyway.

@TheNoumanDev

Copy link
Copy Markdown
Contributor Author

Hey @MAUstaoglu, made all requested changes. Also verified on the simulator.

How do you catch all this? Genuinely asking; I need that Claude skill 😭😭 🥹

@MAUstaoglu

Copy link
Copy Markdown
Member

Honestly, there's no magic 😄 I just know how our plugin structure works (how a port relates to its upstream, where versions get pinned, which files tend to go stale), so I point my agent at the things likely to break. Claude does the review and writes up the findings, then I read through them and sign off on what goes out.

Thanks for the quick turnaround, and for the before/after simulator check on the App Attest fallback!

@MAUstaoglu MAUstaoglu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All five points addressed, thanks. Approving.

One optional nit, not blocking: in AppCheckProviderWrapper.configure, the tvOS #else branch of case "recaptcha": only prints. On a first activate() that's fine since delegateProvider starts as nil, but if an app activates with DeviceCheck and later re-activates with reCAPTCHA, the old DeviceCheck provider stays in place. That contradicts the new README row ("provider is left unconfigured"). A one-liner fixes it:

#else
  delegateProvider = nil
  print("Firebase App Check: reCAPTCHA App Check is not supported on tvOS; use DeviceCheck or App Attest.")
#endif

This behavior is inherited from upstream's macOS branch, so feel free to leave it for a follow-up.

@MAUstaoglu
MAUstaoglu merged commit 9cba25e into fluttertv:main Sep 18, 2026
27 checks passed
@TheNoumanDev

Copy link
Copy Markdown
Contributor Author

@MAUstaoglu, Thanks boss

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