Skip to content

feat(firebase): tvOS support for firebase_ai - #21

Merged
MAUstaoglu merged 4 commits into
fluttertv:mainfrom
TheNoumanDev:feat/firebase-ai-tvos
Aug 18, 2026
Merged

feat(firebase): tvOS support for firebase_ai#21
MAUstaoglu merged 4 commits into
fluttertv:mainfrom
TheNoumanDev:feat/firebase-ai-tvos

Conversation

@TheNoumanDev

@TheNoumanDev TheNoumanDev commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds federated firebase_ai_tvos — Firebase AI Logic (Gemini Developer API + Vertex AI) for Apple TV. Re-exports the firebase_ai Dart API and ships the native tvOS pluginClass. Full API, no feature disables. firebase_ai's requests run in Dart over HTTPS, so the native layer is just a one-method channel (getPlatformHeaders) — this package has no Firebase native SDK dependency and does not depend on firebase_core_tvos (the consuming app brings that for Firebase.initializeApp).

Package(s) touched: firebase_ai_tvos (new)

How was it tested?

Verified on both the tvOS simulator and a physical Apple TV 4K (release/AOT) against a live Firebase project with AI Logic enabled. FirebaseAI.googleAI().generativeModel('gemini-flash-latest').generateContent(...) executed on tvOS, the request reached the Gemini backend and was authenticated + model-resolved — confirmed on-device by pulling the app's written result off the device with devicectl device copy from. Returning generated content additionally requires the project to have Gemini API billing/credits (the test project's were depleted, so the backend returned a billing message — which itself proves the full native→Dart→backend round-trip works on tvOS). Platform.operatingSystem == "tvos" / Platform.isIOS == true.

  • Ran the package's example/ app
  • Verified on tvOS simulator (26.2) — authenticated generateContent round-trip to a live project
  • Verified on a physical Apple TV 4K (release/AOT) — same authenticated round-trip on-device
  • dart analyze is clean for the package

Versioning & changelog

  • version: set to 0.0.1 (new package)
  • Matching ## 0.0.1 entry at the top of CHANGELOG.md
  • No behaviour change (new package)
  • Semver 0.x: initial 0.0.1

Checklist

  • Only firebase_ai_tvos files are touched
  • No secrets, absolute local paths, or TODO/debug leftovers
  • README.md documents tvOS behaviour (full API; version-alignment note)

Notes for reviewers

  • Tracks firebase_ai 3.13.1 on the firebase_core 4.11.x train (same train as the other Firebase _tvos packages).
  • Manual work beyond the auto-port: podspec (tvOS 15, static_framework, no Firebase/firebase_core_tvos pod — native side doesn't touch the Firebase SDK); generated tvos/Package.swift removed; Dart re-export. No firebase_core import to repoint (the plugin doesn't import it).

Realted issue: #14

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

Review

Approving — this is the cleanest port of the seven. CI is green (18/18), and there is nothing in the native layer to argue with.

The port is byte-identical to upstream

tvos/Classes/FirebaseAIPlugin.swift matches upstream firebase_ai 3.13.1's ios/.../FirebaseAIPlugin.swift exactly — diff is empty. Not "three necessary hunks": zero. That works because upstream branches on canImport(FlutterMacOS) rather than os(iOS), so the tvOS build takes the right arm without help.

The podspec is right for the same reason the others' are, and then some: upstream's declares s.dependency 'Flutter', which this correctly drops — that pod has no tvOS platform, and FRAMEWORK_SEARCH_PATHS covers it. No Firebase dependency at all, which matches the package's actual shape: one method channel returning x-ios-bundle-identifier, with every Gemini/Imagen request made from Dart over HTTPS.

The verification write-up is honest in the way I like — you state that the test project's Gemini credits were depleted and the backend answered with a billing message, and then explain why that still proves the round trip. That is more useful than a green tick.


One note, not a request

The README says the consuming app needs firebase_core_tvos for Firebase.initializeApp. Correct — and worth saying that this is sufficient only for the base case.

firebase_ai attaches App Check and Auth tokens to its request headers when those services are registered (base_model.dart:283-302):

final effectiveAppCheck = appCheck ?? app?.getService<FirebaseAppCheck>();
final effectiveAuth     = auth     ?? app?.getService<FirebaseAuth>();

I traced what makes those non-null, since it decides whether this matters. FirebaseApp.getService<T>() reads _registries[name]?[T], and the only thing that populates it is registerService<T>, which each package calls inside its own instanceForfirebase_app_check/lib/src/firebase_app_check.dart:46 and firebase_auth/lib/src/firebase_auth.dart:49. So the pubspec dependency alone registers nothing: an app that never touches FirebaseAppCheck.instance gets null here, both branches are skipped, and no native call is made. That is why plain Gemini works on tvOS with firebase_core_tvos alone, exactly as your device run showed.

The gap is the other two cases. An app using App Check alongside Gemini will have firebase_ai call getToken(), which needs firebase_app_check_tvos — currently #18, not yet merged. One using Auth will hit getIdToken(), needing firebase_auth_tvos, which is already on main. Two lines next to the existing dependency block would save someone a MissingPluginException they would have no reason to expect from a package that "runs in Dart over HTTPS".

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

Agree with skipping both the Firebase pod and the firebase_core_tvos dep — with the native side down to getPlatformHeaders there's nothing to link, and the README says plainly that the app still needs core itself. Publishes clean.

Only thing I'd consider: firebase_ai: ^3.13.1 admits 3.15.0, two minors past what this was generated and verified against. Low risk given there's no platform-interface package, but the README's version-alignment note says 3.13.1 and the constraint doesn't. Fine to leave. LGTM.

@MAUstaoglu
MAUstaoglu merged commit 534a6f7 into fluttertv:main Aug 18, 2026
20 checks passed
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.

3 participants