Skip to content

fix(messaging, ios): read isRegisteredForRemoteNotifications on main queue in getConstants - #9340

Open
roidayan1 wants to merge 1 commit into
invertase:mainfrom
roidayan1:roid/messaging-ios-main-thread-constant
Open

roidayan1 wants to merge 1 commit into
invertase:mainfrom
roidayan1:roid/messaging-ios-main-thread-constant

Conversation

@roidayan1

Copy link
Copy Markdown

Description

Under the New Architecture, getConstants on an iOS TurboModule is invoked synchronously on the JS thread. RNFBMessagingModule's messagingConstantsDictionary (behind constantsToExport / getConstants) reads -[UIApplication isRegisteredForRemoteNotifications], and UIApplication is main-thread only. The module's requiresMainQueueSetup returns NO, so nothing moves this read onto main.

When the app runs under the Xcode debugger on a physical device, Main Thread Checker reports this on every launch:

Main Thread Checker: UI API called on a background thread: -[UIApplication isRegisteredForRemoteNotifications]

The backtrace, on thread com.facebook.react.runtime.JavaScript:

-[RNFBMessagingModule messagingConstantsDictionary]
-[RNFBMessagingModule constantsToExport]
-[RNFBMessagingModule getConstants]
facebook::react::ObjCTurboModule::performMethodInvocation

Fix: read that one value through React Native's RCTUnsafeExecuteOnMainQueueSync (from <React/RCTUtils.h>, which this file already imports). The helper runs the block inline when the caller is already on main. This is the explicit per-call dispatch that NewArch-AD-9 prescribes ("Any genuinely main-thread/UIKit work in getConstants/init is dispatched explicitly to the main queue"). initializeApp in RNFBAppModule already uses the same pattern. requiresMainQueueSetup stays NO, and the TARGET_IPHONE_SIMULATOR branch is unchanged.

Scope notes:

  • Like any synchronous hop to main, this blocks the JS thread until main runs the block. It is a single property read. React Native uses the same mechanism for main-queue module constants.
  • The other isRegisteredForRemoteNotifications reads, in getToken, getAPNSToken and registerForRemoteNotifications, are untouched. This PR only covers the getConstants path that Main Thread Checker flagged.

Related issues

None found. I searched for isRegisteredForRemoteNotifications, "Main Thread Checker" and "UI API called on a background thread". The closest match is #507 (closed, 2017), which is about a different call, registerForRemoteNotifications.

Release Summary

fix(messaging, ios): read isRegisteredForRemoteNotifications on the main queue when building module constants, which stops the Main Thread Checker warning under the New Architecture.

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
    • Yes
  • My change supports the following platforms;
    • Android
    • iOS
    • Other (macOS, web)
  • My change includes tests;
    • e2e tests added or updated in packages/\*\*/e2e
    • jest tests added or updated in packages/\*\*/__tests__
  • I have updated TypeScript types that are affected by my change.
  • This is a breaking change;
    • Yes
    • No

The change is iOS-only because Android has no equivalent main-thread read. There are no API or type changes: the constant has the same name, type and value.

Test Plan

  • Ran the repo's iOS format check on the changed file (the same flags as yarn lint:ios:check) with the lockfile's clang-format@1.8.0 (clang-format 15.0.0): clang-format --style=Google -n -Werror packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.mm. It passes.
  • The Main Thread Checker report and backtrace above come from a New Architecture app on a physical iOS device under the Xcode debugger.
  • I did not build or run the repo's e2e or XCTest suites against this branch, and I have not re-run the device check with this exact patch applied. CI and reviewers should confirm those.

🔥

🤖 Generated with Claude Code

…queue in getConstants

Under TurboModules getConstants is invoked synchronously on the JS thread,
so messagingConstantsDictionary called -[UIApplication
isRegisteredForRemoteNotifications] off the main thread, which Main Thread
Checker reports on every launch. Read that single value through
RCTUnsafeExecuteOnMainQueueSync (runs inline when already on main), as
NewArch-AD-9 prescribes, keeping requiresMainQueueSetup = NO.
@CLAassistant

CLAassistant commented Sep 24, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

No deployments
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