You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo托管RN应用无特殊权限时TestFlight启动EXC_CRASH崩溃求助

Expo应用TestFlight启动触发EXC_CRASH(SIGABRT)排查方案

问题概述

  • 技术栈:Expo托管模式React Native应用,Firebase认证,react-navigation导航
  • 现象:Expo Go、EAS Build开发包、模拟器运行正常,上传TestFlight后启动立刻崩溃,报错类型为EXC_CRASH (SIGABRT)
  • 前置排除项:应用未申请特殊系统权限,常规权限缺失类解决方案不适用,已耗时一周未定位根因

崩溃日志片段(原始应用名已替换为TestApp)

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  2

Last Exception Backtrace:
0   CoreFoundation                  0x1c29f1d78 __exceptionPreprocess + 220 (NSException.m:200)
1   libobjc.A.dylib                 0x1db656734 objc_exception_throw + 60 (objc-exception.mm:565)
2   TestApp                             0x104c89e7c RCTFatal + 668 (RCTAssert.m:146)
3   TestApp                             0x104d08f38 -[RCTExceptionsManager reportFatal:stack:exceptionId:] + 488 (RCTExceptionsManager.mm:68)
4   TestApp                             0x104d09818 -[RCTExceptionsManager reportException:] + 1408 (RCTExceptionsManager.mm:135)
5   CoreFoundation                  0x1c297a614 __invoking___ + 148
6   CoreFoundation                  0x1c2998100 -[NSInvocation invoke] + 468 (NSForwarding.m:3378)
7   CoreFoundation                  0x1c29cf13c -[NSInvocation invokeWithTarget:] + 80 (NSForwarding.m:3475)
8   TestApp                             0x104cbca48 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 460 (RCTModuleMethod.mm:584)
9   TestApp                             0x104cbf03c facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&, int, (anonymous namespace)::SchedulingContext) + 540 (RCTNativeModule.mm:183)
10  TestApp                             0x104cbec6c operator() + 68 (RCTNativeModule.mm:104)
11  TestApp                             0x104cbec6c invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int) + 112 (RCTNativeModule.mm:95)
12  libdispatch.dylib               0x1c2656e68 _dispatch_call_block_and_release + 32 (init.c:1517)
13  libdispatch.dylib               0x1c2658a2c _dispatch_client_callout + 20 (object.m:560)
14  libdispatch.dylib               0x1c2660124 _dispatch_lane_serial_drain + 668 (inline_internal.h:2622)
15  libdispatch.dylib               0x1c2660c80 _dispatch_lane_invoke + 392 (queue.c:3944)
16  libdispatch.dylib               0x1c266b500 _dispatch_workloop_worker_thread + 648 (queue.c:6732)
17  libsystem_pthread.dylib         0x23394e0bc _pthread_wqthread + 288 (pthread.c:2599)
18  libsystem_pthread.dylib         0x23394de5c start_wqthread + 8

从栈信息可以确认,崩溃是React Native层捕获到JS致命错误后调用RCTFatal主动终止进程导致,属于JS/原生模块层错误,和系统权限无关。

问题代码片段(App.js)

initializeApp(firebaseConfig);
const Tab = createMaterialBottomTabNavigator();
const Stack = createNativeStackNavigator();
const [user, setUser] = useState(false);
const [loading, setLoading] = useState(true);
const auth = getAuth(); 
onAuthStateChanged(auth, (user) => {
        if (user) {
            setUser(true);
        } else {
            setUser(false);
        }
        setLoading(false);
     });    
if(loading){
return(<AppLoading />)
}

return (
        <SafeAreaProvider>
            <NavigationContainer>
                {user ? (
                    <MainApp />
                ) : (
                    <Onboarding />
                )}
            </NavigationContainer>
        </SafeAreaProvider>
    );

项目依赖配置

"dependencies": {
    "@emotion/styled": "^11.9.3",
    "@expo/vector-icons": "^13.0.0",
    "@mui/icons-material": "^5.8.4",
    "@react-native-async-storage/async-storage": "~1.17.3",
    "@react-native-clipboard/clipboard": "^1.10.0",
    "@react-native-community/masked-view": "^0.1.11",
    "@react-navigation/material-bottom-tabs": "^6.2.1",
    "@react-navigation/native": "^6.0.10",
    "@react-navigation/native-stack": "^6.6.2",
    "@react-navigation/stack": "^6.2.1",
    "@react-spring/native": "^9.4.5",
    "axios": "^0.27.2",
    "expo": "~45.0.0",
    "expo-app-loading": "~2.0.0",
    "expo-fast-image": "^1.1.3",
    "expo-file-system": "~14.0.0",
    "expo-linking": "~3.1.0",
    "expo-modules-autolinking": "~0.8.1 || ~0.9.0",
    "expo-react-native-fast-image": "^2.0.0",
    "expo-splash-screen": "~0.15.1",
    "expo-status-bar": "~1.3.0",
    "expo-system-ui": "~1.2.0",
    "firebase": "^9.8.4",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-native": "0.68.2",
    "react-native-gesture-handler": "~2.2.1",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-paper": "^4.12.1",
    "react-native-safe-area-context": "4.2.4",
    "react-native-unimodules": "^0.15.0",
    "react-native-web": "0.17.7",
    "react-progressive-graceful-image": "^0.6.14",
    "react-spring": "^8.0.27",
    "react-tinder-card": "^1.4.5"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/plugin-proposal-export-namespace-from": "^7.18.6",
    "@types/react": "~17.0.21",
    "@types/react-native": "~0.67.6",
    "typescript": "~4.3.5"
  },

已尝试的排查操作

  • 卸载、重新安装并校验多个版本的Expo与React Native依赖
  • 移除所有Firebase认证相关钩子逻辑
  • 重构应用认证流程代码
  • 将Firebase初始化逻辑从App.js导出组件外部移动到组件内部

根因与修复方案

1. 依赖冲突与无效依赖导致release构建崩溃

开发模式下Metro打包会跳过部分导入错误、容忍重复模块注册,但TestFlight使用的release发行构建会严格校验所有模块,以下依赖问题会直接触发致命错误:

  • 同时安装了expo-fast-image和expo-react-native-fast-image两个功能完全重复的原生图片库,二者会注册同名原生模块导致冲突,直接卸载两个包即可,Expo 45如需图片缓存能力使用官方维护的expo-image。
  • 安装了@mui/icons-material、@emotion/styled、react-dom、react-native-web等Web端专属依赖,其中@mui/icons-material依赖浏览器DOM API,在原生环境下导入会直接抛出找不到window/document对象的错误,全部卸载即可。
  • 安装了已废弃的@react-native-community/masked-view,Expo 45已内置@react-native-masked-view/masked-view,旧包会出现原生模块不匹配问题,直接卸载。
  • 安装了Expo 45及以上版本完全废弃的react-native-unimodules,残留配置会导致原生模块链接错误,直接卸载。

2. React Hooks调用位置违规

从代码片段可见,useState、onAuthStateChanged的调用写在了函数组件外部,违反React Hooks只能在组件顶层调用的规则,开发模式下热重载可能暂时掩盖问题,release模式下会直接抛出Hooks调用无效的致命错误。修复后代码参考:

import { useEffect, useState } from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import AppLoading from 'expo-app-loading';
import MainApp from './MainApp';
import Onboarding from './Onboarding';

// Firebase初始化可放在组件外,仅执行一次
initializeApp(firebaseConfig);
const Tab = createMaterialBottomTabNavigator();
const Stack = createNativeStackNavigator();

export default function App() {
  // 所有Hooks移到组件内部顶层
  const [user, setUser] = useState(false);
  const [loading, setLoading] = useState(true);
  const auth = getAuth();

  useEffect(() => {
    // 注册认证状态监听
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(!!currentUser);
      setLoading(false);
    });
    // 组件卸载时取消订阅,避免内存泄漏
    return () => unsubscribe();
  }, []);

  if(loading){
    return <AppLoading />
  }

  return (
    <SafeAreaProvider>
      <NavigationContainer>
        {user ? <MainApp /> : <Onboarding />}
      </NavigationContainer>
    </SafeAreaProvider>
  );
}

3. 本地debug技巧

不需要等TestFlight包崩溃再猜问题,直接用EAS打本地release构建包,连接Mac打开Xcode控制台查看运行日志,就能直接看到具体的JS报错行号和错误信息,比崩溃日志的原生栈信息精准很多。


内容的提问来源于stack exchange,提问作者John Stanwick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 02:57:09