iOS端NSInternalInconsistencyException崩溃求助(关联Firebase远程通知)
NSInternalInconsistencyException崩溃的分析与修复方案 Hey there, let’s break down this crash issue you’ve been stuck on for days. First, recap the key details: this started popping up after integrating Firebase SDK, it’s getting more frequent over time, and you suspect it’s tied to remote notifications. Let’s dive into the root cause and fixes.
核心崩溃信息
The crash triggers an NSInternalInconsistencyException with this critical message:
this request has been neutered - you can't call -sendResponse: twice nor after encoding it
Here’s the full crash stack for reference:
Fatal Exception: NSInternalInconsistencyException 0 CoreFoundation 0x1c2726ab8 __exceptionPreprocess 1 libobjc.A.dylib 0x1c192bd00 objc_exception_throw 2 CoreFoundation 0x1c263be90 +[_CFXNotificationTokenRegistration keyCallbacks] 3 Foundation 0x1c3117cfc -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 4 BaseBoard 0x1c4f2e664 __40-[BSAction sendResponse:withCompletion:]_block_invoke 5 libdispatch.dylib 0x1c2135888 _dispatch_client_callout 6 libdispatch.dylib 0x1c2142404 _dispatch_lane_barrier_sync_invoke_and_complete 7 BaseBoard 0x1c4ee2b84 -[BSAction sendResponse:withCompletion:] 8 UIKitCore 0x1ef72bf84 -[UIHandleRemoteNotificationAction sendResponse:] 9 UIKitCore 0x1efb69028 __91-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:]_block_invoke_3.2678 10 UIKitCore 0x1efb69b4c __125-[UIApplication _updateStateRestorationArchiveForBackgroundEvent:saveState:exitIfCouldNotRestoreState:updateSnapshot:canvas:]_block_invoke_2 11 libdispatch.dylib 0x1c2134308 _dispatch_call_block_and_release 12 libdispatch.dylib 0x1c2135888 _dispatch_client_callout 13 libdispatch.dylib 0x1c214173c _dispatch_main_queue_callback_4CF 14 CoreFoundation 0x1c26b6734 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ 15 CoreFoundation 0x1c26b13e4 __CFRunLoopRun 16 CoreFoundation 0x1c26b0964 CFRunLoopRunSpecific 17 GraphicsServices 0x1c48f1d8c GSEventRunModal 18 UIKitCore 0x1efb51758 UIApplicationMain 19 XXXX 0x1023e1480 main + 26 (AppDelegate.swift:26) 20 libdyld.dylib 0x1c216cfd8 start Crashed: com.twitter.crashlytics.ios.exception 0 XXXX 0x102692000 CLSProcessRecordAllThreads + 4305018880 1 XXXX 0x1026923e8 CLSProcessRecordAllThreads + 4305019880 2 XXXX 0x102681c60 CLSHandler + 4304952416 3 XXXX 0x102690604 __CLSExceptionRecord_block_invoke + 4305012228 4 libdispatch.dylib 0x1c2135888 _dispatch_client_callout + 20 5 libdispatch.dylib 0x1c2142404 _dispatch_lane_barrier_sync_invoke_and_complete + 60 6 XXXX 0x102690070 CLSExceptionRecord + 4305010800 7 XXXX 0x10268fe9c CLSExceptionRecordNSException + 4305010332 8 XXXX 0x10268fa90 CLSTerminateHandler() + 4305009296 9 libc++abi.dylib 0x1c19209cc std::__terminate(void (*)()) + 20 10 libc++abi.dylib 0x1c1920a40 std::terminate() + 60 11 libobjc.A.dylib 0x1c192c09c _destroyAltHandlerList + 14 12 libdispatch.dylib 0x1c213589c _dispatch_client_callout + 40 13 libdispatch.dylib 0x1c2142404 _dispatch_lane_barrier_sync_invoke_and_complete + 60 14 BaseBoard 0x1c4ee2b84 -[BSAction sendResponse:withCompletion:] + 148 15 UIKitCore 0x1ef72bf84 -[UIHandleRemoteNotificationAction sendResponse:] + 148 16 UIKitCore 0x1efb69028 __91-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:]_block_invoke_3.2678 + 76 17 UIKitCore 0x1efb69b4c __125-[UIApplication _updateStateRestorationArchiveForBackgroundEvent:saveState:exitIfCouldNotRestoreState:updateSnapshot:canvas:]_block_invoke_2 + 264 18 libdispatch.dylib 0x1c2134308 _dispatch_call_block_and_release + 32 19 libdispatch.dylib 0x1c2135888 _dispatch_client_callout + 20 20 libdispatch.dylib 0x1c214173c _dispatch_main_queue_callback_4CF + 1012 21 CoreFoundation 0x1c26b6734 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 22 CoreFoundation 0x1c26b13e4 __CFRunLoopRun + 1888 23 CoreFoundation 0x1c26b0964 CFRunLoopRunSpecific + 452 24 GraphicsServices 0x1c48f1d8c GSEventRunModal + 108 25 UIKitCore 0x1efb51758 UIApplicationMain + 216 26 XXXX 0x1023e1480 main + 26 (AppDelegate.swift:26) 27 libdyld.dylib 0x1c216cfd8 start
问题根源分析
Looking at the stack trace, the crash happens because the sendResponse: method on UIHandleRemoteNotificationAction is being called twice—or called after the response has already been encoded. Given the Firebase SDK context, here are the most likely culprits:
- A conflict between Firebase Cloud Messaging (FCM) and Apple’s native remote notification handling logic
- Duplicate code paths where both your custom notification handling and FCM’s callbacks are triggering a response send
- Race conditions in background notification processing that cause the response to be sent multiple times
修复建议
Let’s go through actionable steps to fix this:
1. Eliminate duplicate notification handling logic
Check if you’re implementing both Apple’s native notification delegates (like userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:) and FCM’s callbacks (like messaging:didReceiveRemoteMessage:). If both are processing the same notification, you might be accidentally sending the response twice. Pick one path to handle notification actions, or add checks to ensure only one path executes.
2. Ensure response is sent exactly once
Add a guard flag to your notification handling code to prevent duplicate calls to the completion handler (which under the hood triggers sendResponse:). Here’s a Swift example:
private var hasSentNotificationResponse = false func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { guard !hasSentNotificationResponse else { completionHandler() return } hasSentNotificationResponse = true // Your notification action processing logic here completionHandler() }
3. Update Firebase SDK and verify configuration
Outdated FCM versions might have compatibility issues with iOS’s notification framework. Update to the latest stable Firebase SDK version. Also, double-check your Info.plist to ensure there are no duplicate FCM-related entries that could cause multiple registrations.
4. Fix thread safety in background processing
Background notification operations can run on non-main threads, which might lead to race conditions. Wrap your completion handler call in the main queue to ensure it executes safely:
DispatchQueue.main.async { completionHandler() }
5. Check for third-party library conflicts
If you’re using other notification-related libraries alongside FCM, they might be interfering with each other. Temporarily disable other libraries to see if the crash frequency drops, then debug the conflict if that’s the case.
内容的提问来源于stack exchange,提问作者phage04

