fix: [SDK-4946] register with Firebase Installation ID when the legacy FCM token API is disabled - #2734
Conversation
📊 Diff Coverage ReportDiff Coverage Report (Changed Lines Only)Gate: aggregate coverage on changed executable lines must be ≥ 80% (JaCoCo line data for lines touched in the diff). Changed Files Coverage
Overall (aggregate gate)78/78 touched executable lines covered (100.0% — requires ≥ 80%) |
There was a problem hiding this comment.
Multi-model review
Claude Opus 5, GPT 5.6 Sol, and Cursor Grok 4.6 reviewed the FID fallback (5 files, +463/−9). No blocking issues. The happy path is sound: keep using named-app getToken() until Firebase throws the V1 “API disabled” ISE, then register() + FID on the host default FirebaseApp only when its sender matches.
Act on
- Named app is still created when V1 is the only viable path (Opus + Grok).
getTokenalways initializesONESIGNAL_SDK_FCM_APP_NAME(dashboard sender + OneSignal shared credentials) and calls.tokenbefore the default-app FID path. With the legacy API disabled process-wide that call is guaranteed to fail, and constructingFirebaseMessagingon the mixed app can still kick a background register against credentials this PR says Firebase rejects (#2700 sawopStatusCode=8/ topic-sync noise from that app). If the flag is on andregister()exists, skip named-app init and go straight todefaultAppRegistration().
Consider
- FID rotation (GPT; Opus adjacent).
register()on the host default app can fire the hostonRegisteredcallback and does not consultisAutoInitEnabled(). OneSignal has no FCMonNewToken/onRegisteredbridge, so a later FID change is not uploaded until another SDK registration. - Fragile disable detection + no 25.1 fixture (3/3). Fallback is a substring match on
"API disabled"+"register()", and reflection/ProGuard are only tested against hand-rolled stand-ins while the module resolves 24.0.0. A wording or signature change ships asFIREBASE_FCM_ERROR_MISC_EXCEPTIONwith no retry. - Diagnostics land in the misc bucket (Opus + Grok). Sender mismatch / missing default app (common when a dependency injects the flag and the dashboard is still on the shared sender) is a permanent config error logged as “Unknown error getting FCM Token”.
- FidEnv vs this path (Opus). Census still uses
getManifestMetaBoolean+gcm_defaultSenderId; registration uses a raw meta read +FirebaseApp.options. Programmatic default apps can reportflag=0/snd=0even when this path would succeed.
Dismissed
- FID uploaded as a normal push token — that is the feature contract.
defaultSenderId("")not falling back to the applicationId parse — matches FirebaseMetadata.getDefaultSenderId.- Gradle
require '[23.0.8, 24.0.99]'— pre-existing;requireis not a hard upper bound. Tasks.awaitwithout timeout and the uncheckedas Task<*>— same await as the existing token path; the cast is a nit.
Sent by Cursor Automation: PR Reviews
73cff6b to
d328c38
Compare
abdulraqeeb33
left a comment
There was a problem hiding this comment.
Looks right. Flag off stays on the named app. FID only uses the host default FirebaseApp, and only when the sender matches.
abdulraqeeb33
left a comment
There was a problem hiding this comment.
nit and a question
…I is disabled Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
b862679 to
f21caa0
Compare


Description
One Line Summary
Restore Firebase Installation ID registration when an app disables the legacy FCM token API.
Details
Motivation
Firebase Messaging 25.1.0 allows apps and dependencies to enable
firebase_messaging_installation_id_enabled, which disables the legacy token API process-wide. OneSignal'sgetToken()then throwsIllegalStateException: API disabled, preventing push registration.This remakes #2700 after its temporary revert in #2719. It retains the original fallback and diagnostics, and now mirrors Firebase Messaging's sender-ID fallback for programmatically configured default Firebase apps.
Scope
Only the FCM registration path changes when Firebase reports that the legacy API is disabled. Existing integrations continue using
getToken().FID registration uses the host app's default
FirebaseApp, because its sender ID, app ID, and API key belong to one Firebase project. Apps enabling FID registration must provide Firebase configuration whose sender ID matches the OneSignal dashboard.FirebaseMessaging.register()remains reflective so the SDK can compile against Firebase Messaging 24.0.0 while consumers resolve 25.1.0 or newer. The consumer rule preserves this method through minification.Testing
Unit testing
FirebaseApp../gradlew spotlessCheck detekt :OneSignal:notifications:testDebugUnitTest :OneSignal:notifications:assembleRelease --console=plainManual testing
The original implementation was manually verified on an Android 16 emulator with Firebase Messaging 25.1.1 in both debug and minified release builds, including delivery and legacy-token/FID conversion. This remake restores that implementation; the added sender fallback is covered by unit tests and was not re-tested on-device.
Affected code checklist
Checklist
Overview
Testing
Final pass
Made with Cursor