Search code examples
reactjsexponative

React Expo app crashing on tap on any component in production


App is working on Expo Go without any error but it's not working after releasing for testing on play store. App crashes on touch on any button or text input (basically any component on screen but not on empty space).

Error#1 from play store console

Exception com.facebook.react.common.JavascriptException: TypeError: null is not an object (evaluating 'v.default.handleSetJSResponder'), stack:
<unknown>@1370:7569
onChange@31:15628
K@31:5477
extractEvents@31:9261
<unknown>@31:14593
Ce@31:98527
Ne@31:14128
Me@31:14505
receiveTouches@31:15298
value@61:3821
<unknown>@61:759
value@61:2583
value@61:731
value@-1
  at com.facebook.react.modules.core.ExceptionsManagerModule.reportException (ExceptionsManagerModule.java:72)
  at java.lang.reflect.Method.invoke
  at com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
  at com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:188)
  at com.facebook.jni.NativeRunnable.run
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:228)
  at java.lang.Thread.run (Thread.java:920)

Error#2 from play store console

Exception java.lang.RuntimeException: Unable to start receiver com.google.android.finsky.instantapps.PhenotypeUpdateReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.android.gms.phenotype.UPDATE cmp=com.android.vending/com.google.android.finsky.instantapps.PhenotypeUpdateService }: app is in background uid UidRecord{b2cad2c u0a252 TRNB bg:+7m41s887ms idle change:uncached procs:2 proclist:5053,30011, seq(0,0,0)}
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:4120)
  at android.app.ActivityThread.access$1700 (ActivityThread.java:272)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2066)
  at android.os.Handler.dispatchMessage (Handler.java:107)
  at android.os.Looper.loop (Looper.java:237)
  at android.app.ActivityThread.main (ActivityThread.java:8016)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1076)
Caused by java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.android.gms.phenotype.UPDATE cmp=com.android.vending/com.google.android.finsky.instantapps.PhenotypeUpdateService }: app is in background uid UidRecord{b2cad2c u0a252 TRNB bg:+7m41s887ms idle change:uncached procs:2 proclist:5053,30011, seq(0,0,0)}
  at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1688)
  at android.app.ContextImpl.startService (ContextImpl.java:1633)
  at android.content.ContextWrapper.startService (ContextWrapper.java:683)
  at alj.a (PG:2)
  at alm.a (PG:3)
  at wnv.a (PG:2)
  at com.google.android.finsky.instantapps.PhenotypeUpdateReceiver.onReceive (PG:6)
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:4111)

app.json

{
  "expo": {
    "name": "App name",
    "slug": "native-app",
    "version": "1.0.2",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "packagerOpts": {
      "sourceExts": [
        "expo.ts",
        "expo.tsx",
        "expo.js",
        "expo.jsx",
        "ts",
        "tsx",
        "js",
        "jsx",
        "json",
        "wasm",
        "svg"
      ]
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/icon.png",
        "backgroundColor": "#FFFFFF"
      },
      "versionCode": 3,
      "package": "com.deepakpunia.nativeapp"
    },
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "extra": {
      "eas": {
        "projectId": "b1a9d6d8-ba07-49aa-8b90-ebc08bd07da5"
      }
    }
  }
}

package.json

{
  "name": "native-app",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@expo/webpack-config": "^0.17.2",
    "@react-navigation/drawer": "^6.5.0",
    "@react-navigation/native": "^6.0.13",
    "@react-navigation/native-stack": "^6.9.1",
    "@reduxjs/toolkit": "^1.9.0",
    "axios": "^1.1.3",
    "expo": "~47.0.5",
    "expo-image-picker": "~14.0.2",
    "expo-location": "~15.0.1",
    "expo-secure-store": "~12.0.0",
    "expo-status-bar": "~1.4.2",
    "react": "18.1.0",
    "react-dom": "18.1.0",
    "react-native": "0.70.5",
    "react-native-chart-kit": "^6.12.0",
    "react-native-dropdown-picker": "^5.4.3",
    "react-native-paper": "^5.0.0-rc.10",
    "react-native-reanimated": "^2.12.0",
    "react-native-safe-area-context": "4.4.1",
    "react-native-screens": "~3.18.0",
    "react-native-select-dropdown": "^3.0.3",
    "react-native-signature-canvas": "^4.4.1",
    "react-native-svg": "^13.4.0",
    "react-native-web": "~0.18.9",
    "react-redux": "^8.0.5"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9"
  },
  "private": true
}

App.js

const Stack = createNativeStackNavigator();
function CustomDrawerContent(props) {
  const dispatch = useDispatch();
  const user = useSelector((state) => state.auth.user);
  const profile = useSelector((state) => state.profile.profile);
  
  
  return (
    <DrawerContentScrollView {...props}>
      <View
        style={[
          styles.my5,
          styles.flex,
          styles.alignItemsCenter,
          styles.justifyContentCenter,
        ]}
      >
        {profile?.profilePicture ? (
          <Avatar.Image
            size={100}
            source={{uri: `${API_ENDPOINT}/${
              profile.profilePicture
            }`}} 
            
          />
        ) : (
          <Avatar.Icon size={100} icon="account" />
        )}

        <Text style={[styles.capitalLetter, styles.my2, styles.textMd]}>{user.username}</Text>
      </View>
      <>
        <Divider />
      </>
      <DrawerItemList {...props} />

      <DrawerItem
        label="Logout"
        onPress={() => dispatch(logout())}
        icon={({ color, size }) => (
          <MaterialCommunityIcons name="logout" size={size} color={color} />
        )}
      />
      {/* <DrawerItem
        label="Close drawer"
        onPress={() => props.navigation.closeDrawer()}
        icon={({ color, size }) => (
          <AntDesign name="closecircleo" size={size} color={color} />
        )}
      /> */}
    </DrawerContentScrollView>
  );
}

const Drawer = createDrawerNavigator();

function MyDrawer() {
  return (
    <Drawer.Navigator
      useLegacyImplementation
      drawerContent={(props) => <CustomDrawerContent {...props} />}
    >
      <Drawer.Screen
        name="Dashboard"
        component={Dashboard}
        options={{
          drawerIcon: ({ size, color }) => (
            <AntDesign name="dashboard" size={size} color={color} />
          ),
        }}
      />
      <Drawer.Screen
        name="Profile"
        component={Profile}
        options={{
          drawerIcon: ({ size, color }) => (
            <Feather name="user" size={size} color={color} />
          ),
        }}
      />
      <Drawer.Screen
        name="Schedule"
        component={Schedule}
        options={{
          drawerIcon: ({ size, color }) => (
            <AntDesign name="calendar" size={size} color={color} />
          ),
        }}
      />
      <Drawer.Screen
        name="Openshifts"
        component={Openshifts}
        options={{
          drawerIcon: ({ size, color }) => (
            <MaterialCommunityIcons name="antenna" size={size} color={color} />
          ),
        }}
      />
      <Drawer.Screen
        name="Tasks"
        component={Tasks}
        options={{
          drawerIcon: ({ size, color }) => (
            <Octicons name="tasklist" size={size} color={color} />
          ),
        }}
      />
      <Drawer.Screen
        name="Settings"
        component={Settings}
        options={{
          drawerIcon: ({ size, color }) => (
            <AntDesign name="setting" size={size} color={color} />
          ),
        }}
      />
    </Drawer.Navigator>
  );
}

const MyNavigation = () => {
  const user = useSelector((state) => state.auth);
  if (
    (user.isAuthenticated &&
      (user.user?.roles.includes(UserRoles.ROLE.SOMEROLE) ||
        user.user?.roles.includes(UserRoles.ROLE.SOMEROLE) ||
        user.user?.roles.includes(UserRoles.ROLE.SOMEROLE))) ||
    user.user?.roles.includes(UserRoles.ROLE.SOMEROLE)
  ) {
    return (
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="NoAccess" component={NoAccess} />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
  if (user.isAuthenticated && user.user?.roles.includes(UserRoles.ROLE.SOMEROLE)) {
    return (
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen
            name="HomePage"
            component={MyDrawer}
            options={{ headerShown: false }}
          />
          <Stack.Screen name="Somecomponent" component={Somecomponent} />
          <Stack.Screen name="Somecomponent" component={Somecomponent} />
          <Stack.Screen name="Somecomponent" component={Somecomponent} />
          <Stack.Screen name="NoAccess" component={NoAccess} />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default function App() {
  return (
    <Provider store={store}>
      {/* {console.log("11111", store.getState())} */}
      <PaperProvider>
        <MyNavigation />
      </PaperProvider>
    </Provider>
  );
}

Only related answer I could find is https://github.com/software-mansion/react-native-gesture-handler/issues/983#issuecomment-592988642 but it's not working.

I am stuck here for all day. Any directions will be helpful.

Update: I am trying to isolate the error by removing drawer navigation and dependencies one by one. I will post all updates here.

Update: Took all day to figure this one out. In production make sure to add react-native-gesture-handler package. App works fine on expo go without it but not in production.


Solution

  • If anyone else is having same issue, add react-native-gesture-handler in dependency

    npm i react-native-gesture-handler