[messaging][ios] APNs token type is inferred from DEBUG instead of the signed APNs environment
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 56/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- firebase, ios, objective-c, react-native
- Domain
- mobile
Research direction
Start in packages/messaging/ios/RNFBMessaging/RNFBMessaging+AppDelegate.m, where the APNs token type is selected from DEBUG. Read Firebase Messaging's supported unknown or autodetected APNs token behavior and determine how the signed aps-environment should drive the association. Done means Release builds signed for development no longer receive a production token type and FCM delivery succeeds.
Written by the indexing model from the issue text.
Description
Issue
On iOS, @react-native-firebase/messaging currently determines the APNs token type from the DEBUG compilation macro in RNFBMessaging+AppDelegate.m:
#ifdef DEBUG
[[FIRMessaging messaging] setAPNSToken:deviceToken
type:FIRMessagingAPNSTokenTypeSandbox];
#else
[[FIRMessaging messaging] setAPNSToken:deviceToken
type:FIRMessagingAPNSTokenTypeProd];
#endif
This assumes that:
DEBUG defined == APNs sandbox
DEBUG not defined == APNs production
However, the build configuration / DEBUG macro and the APNs environment of the signed application are independent.
A valid Release build can be signed using Apple Development provisioning and therefore have:
aps-environment = development
while DEBUG is not defined.
I reproduced this configuration on a physical iPhone.
Reproduction
Environment used for the runtime reproduction:
@react-native-firebase/messaging: 21.14.0
Firebase Messaging iOS SDK: 11.11.0
GoogleUtilities: 8.1.0
Xcode: 27.0
Device: iPhone 16e
iOS: 26.5
The application was:
Build configuration: Release
Signing: Apple Development
Signed aps-environment: development
DEBUG macro in RNFBMessaging: not defined
FirebaseAppDelegateProxyEnabled: not explicitly disabled
The signed application entitlement was verified from the built .app, rather than inferred from the Xcode build configuration.
With the standard RNFirebase AppDelegate integration, the RNFirebase callback therefore selected:
FIRMessagingAPNSTokenTypeProd
even though the signed application was using the APNs development environment.
After obtaining an FCM registration token, sending a real FCM notification resulted in:
HTTP 400
APNs error: BadDeviceToken
Control experiment
In an isolated diagnostic build I disabled the automatic proxy and explicitly associated the APNs token as sandbox as the initial association:
[[FIRMessaging messaging] setAPNSToken:deviceToken
type:FIRMessagingAPNSTokenTypeSandbox];
I then deleted the existing FCM registration token and generated a new one after the correct APNs association.
Using the same physical device and Firebase project, FCM delivery then succeeded.
Multiple subsequent real pushes were successfully delivered.
This was only a diagnostic control; I am not proposing that applications should manually force sandbox.
Why this appears to be incorrect
DEBUG describes how the code was compiled. It is not the authority for the APNs environment used by the signed application.
The APNs environment is determined by the application's signing/provisioning and resulting aps-environment entitlement.
For example, this is a valid combination:
Release configuration
DEBUG not defined
Apple Development signing
aps-environment = development
In that case the current RNFirebase heuristic selects Production while the APNs token belongs to Sandbox.
Conversely, relying on DEBUG could theoretically produce the opposite mismatch for a build where DEBUG is defined but the signed APNs environment is production.
Expected behavior
The APNs token type should not be inferred solely from DEBUG.
It should instead be determined from the actual APNs environment of the signed application, or RNFirebase could potentially allow Firebase Messaging to perform its supported APNs environment autodetection rather than explicitly forcing Sandbox/Prod from the compilation macro.
For example, Firebase Messaging supports an unknown/autodetected APNs token type, although I am not prescribing a specific implementation.
Current upstream source
I originally reproduced the issue with RNFirebase 21.14.0.
I also checked the current main branch and the AppDelegate callback still uses the same #ifdef DEBUG distinction:
I have not repeated the physical-device reproduction against the current main branch, so the runtime reproduction described above should be considered specific to 21.14.0; the current-source observation is source inspection only.
Impact
This does not appear to affect the usual combinations:
Debug + development signing
Release + App Store/TestFlight production signing
because the DEBUG heuristic happens to agree with the APNs environment in those cases.
It can affect valid configurations such as:
Release + development signing
which may be used for internal testing, QA, physical-device testing, or Release-mode builds that need to run without Metro.
In the reproduced case, the user-visible effect was complete FCM push delivery failure due to BadDeviceToken.
- Dominant language
- TypeScript
- Stars
- 12.3k
- Forks
- 2.3k
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 12
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from invertase/react-native-firebase
-
Bump Firebase JS SDK (12.19.0 → 13.0.0)Possibly taken @SelaseKay claimed this 3 days ago. OpenNeeds Attention type: enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
invertase/react-native-firebase#9364 · 1 comment ·
Maintainers usually reply within 1 day
-
Bump Firebase Android SDK (34.19.0 → 35.0.0)Possibly taken @SelaseKay claimed this 3 days ago. OpenNeeds Attention type: enhancement
Difficulty 1/5 Under an hour Newbie friendliness 20/100
invertase/react-native-firebase#9363 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
invertase/react-native-firebase#9360 ·
Maintainers usually reply within 1 day
-
Needs Attention platform: ios plugin: app-core type: bug
Difficulty 4/5 3-5 days Newbie friendliness 25/100
invertase/react-native-firebase#9354 · 3 comments ·
Maintainers usually reply within 1 day
-
🚀 [database] Modular `get()` should use the native one-shot read, not `once('value')`Possibly taken @nickcernera claimed this 15 days ago. Openplatform: android platform: javascript plugin: database type: bug
Difficulty 5/5 Over a week Newbie friendliness 35/100
invertase/react-native-firebase#9344 · 1 comment ·
Maintainers usually reply within 1 day
All issues in invertase/react-native-firebase
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
cline/mcp-marketplace#2932 ·
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 82/100
lingdojo/kana-dojo#32188 · 1 comment · 5 reactions ·
Maintainers usually reply within 1 day
-
triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Portkey-AI/gateway#1844 ·
Maintainers usually reply within 1 day
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 61/100
rjsf-team/react-jsonschema-form#5495 ·
Maintainers usually reply within 2 days