feat(firebase): tvOS support for firebase_ai - #21
Conversation
DenisovAV
left a comment
There was a problem hiding this comment.
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 instanceFor — firebase_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
left a comment
There was a problem hiding this comment.
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.
What does this PR do?
Adds federated
firebase_ai_tvos— Firebase AI Logic (Gemini Developer API + Vertex AI) for Apple TV. Re-exports thefirebase_aiDart API and ships the native tvOSpluginClass. 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 onfirebase_core_tvos(the consuming app brings that forFirebase.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 withdevicectl 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.example/appgenerateContentround-trip to a live projectdart analyzeis clean for the packageVersioning & changelog
version:set to0.0.1(new package)## 0.0.1entry at the top ofCHANGELOG.md0.x: initial0.0.1Checklist
firebase_ai_tvosfiles are touchedTODO/debug leftoversREADME.mddocuments tvOS behaviour (full API; version-alignment note)Notes for reviewers
firebase_ai 3.13.1on thefirebase_core 4.11.xtrain (same train as the other Firebase_tvospackages).static_framework, no Firebase/firebase_core_tvos pod — native side doesn't touch the Firebase SDK); generatedtvos/Package.swiftremoved; Dart re-export. Nofirebase_coreimport to repoint (the plugin doesn't import it).Realted issue: #14