software-mansion / react-native-screens

Native navigation primitives for your React Native app.
https://docs.swmansion.com/react-native-screens/
MIT License
3.1k stars 521 forks source link

RNScreensNavigationController is pushing the same view controller instance more than once #791

Closed birgernass closed 3 years ago

birgernass commented 3 years ago

Description

We are seeing the following crash quite frequently on iOS since we started to use react-native-screens/createNativeStackNavigator. Any help would be much appreciated.

Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 0

Application Specific Information:
<RNScreensNavigationController: 0x1038e6800> is pushing the same view controller instance (<RNSScreen: 0x12f123e20>) more than once which is not supported and is most likely an error in the application

Thread 0 Crashed:
0   CoreFoundation                  0x3259749d8         __exceptionPreprocess
1   libobjc.A.dylib                 0x34e15ab50         objc_exception_throw
2   UIKitCore                       0x3298bc6c0         -[UINavigationController pushViewController:transition:forceImmediate:]
3   UIKitCore                       0x32a4dbfb4         -[_UIAfterCACommitBlock run]
4   UIKitCore                       0x32a041a64         _runAfterCACommitDeferredBlocks
5   UIKitCore                       0x32a030f94         _cleanUpAfterCAFlushAndRunDeferredBlocks
6   UIKitCore                       0x32a062564         _afterCACommitHandler
7   CoreFoundation                  0x3258f3878         __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
8   CoreFoundation                  0x3258edf4c         __CFRunLoopDoObservers
9   CoreFoundation                  0x3258edbf0         CFRunLoopRunSpecific
10  GraphicsServices                0x3533f9594         GSEventRunModal
11  UIKitCore                       0x32a0323d4         -[UIApplication _run]
12  UIKitCore                       0x32a037954         UIApplicationMain
13  ########                        0x200d3d5d4         main (main.m:7)

Steps To Reproduce

We see this crash in our Sentry issues but don't know how to reproduce it yet.

Package versions

WoLewicki commented 3 years ago

I am afraid we cannot do much without the reproduction. From the crash description, it looks like it might be caused by pushing screens too fast leading to some wrong state of navigation stack with 2 same screens, but I cannot say much more.

birgernass commented 3 years ago

I know my information is very limited at this point. Thanks for sharing your thoughts on this.

msvargas commented 3 years ago

I have the same issue, may this help

image

WoLewicki commented 3 years ago

@msvargas are you able to reproduce it on a simple example?

msvargas commented 3 years ago

@msvargas are you able to reproduce it on a simple example?

At the time, I check it occurs rarely when switching auth flow, like this: https://reactnavigation.org/docs/auth-flow/#define-our-screens after user log in and redirect to "Home", I have to errors log with the same iOS version 14.3

WoLewicki commented 3 years ago

So could you post this reproduction? It does not need to be fully deterministic, it needs to be reproducible in finite steps.

lucasjohnston commented 3 years ago

Just popping in to say I have the same issues, using the same auth navigator setup that @msvargas mentioned above. I started with @infinitered's Ignite starter which uses both react-native-screens and react-navigation.

I'm blocked from launching our app until this is resolved, and I've spent a number of hours trying to debug this. The fact others have cropped up with this issue recently makes me think it might be an Ignite navigation boilerplate or a react-native-screens error, but I'm still trying to get to the bottom of it. Will follow up with repro etc soon.

lucasjohnston commented 3 years ago

The error happens here in CallbackScreen.tsx:

type props = StackScreenProps<StackOneParams, 'callback'>

...

useEffect(() => {
  if (conditional) {
    props.navigation.navigate('onboard')
  }
}, [props])

return <View><ActivityIndicator /></View>

When running from xcode (testing on device), the CallbackScreen remains with the spinning activity indicator (ie. no navigation) and Xcode reports the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '<RNScreensNavigationController: 0x10d017e00> is pushing the same view controller instance (<RNSScreen: 0x1089572f0>) more than once which is not supported and is most likely an error in the application : com.appgoeshere'

But after I close and reopen the app on my device (so the device is now communicating with the RN server on my mac without going through xcode), my console logs shows it successfully navigating to our OnboardingScreen and actually running our useEffect() hooks - but then it crashes without any kind of error.

Screenshot 2021-02-20 at 23 30 21

Is there a reason why Xcode would potentially stop a navigation performing whilst in debugging mode?

WoLewicki commented 3 years ago

Can you provide a snack/repo with minimal configuration needed to reproduce the issue?

kacperkapusciak commented 3 years ago

I've managed to reproduce this issue with the following code

import React, {useEffect} from 'react';
import {StyleSheet, Button, View, Text} from 'react-native';
import {enableScreens} from 'react-native-screens';
import {createNativeStackNavigator} from 'react-native-screens/native-stack';

enableScreens();

const MainScreen = ({navigation}) => {
  useEffect(() => {
    navigation.navigate('Modal')
  }, [])

  return (
    <View style={styles.screen}>
      <Text>Issue 791</Text>
    </View>
  )
}

const PushScreen = ({navigation}) => (
  <View style={styles.screen}>
    <Button onPress={() => navigation.push('Push')} title="Mash this button" />
  </View>
);

const Stack = createNativeStackNavigator();

const App = () => (
  <Stack.Navigator>
    <Stack.Screen
      name="Main"
      component={MainScreen}
    />
    <Stack.Screen
      name="Push"
      component={PushScreen}
    />
    <Stack.Screen
      name="Modal"
      component={PushScreen}
      options={{ stackPresentation: 'modal'}}
    />
  </Stack.Navigator>
);

const styles = StyleSheet.create({
  screen: {
    ...StyleSheet.absoluteFillObject,
    flex: 1,
    paddingTop: 200,
    alignItems: 'center',
  },
});

export default App;

This error occurs when you push a 'normal' screen under a modal. Inside modals only pushing modals is supported. Could you check if it's the case within your app?

WoLewicki commented 3 years ago

Can you check if https://github.com/software-mansion/react-native-screens/pull/839 fixes your issues @birgernass @msvargas @lucasjohnston ?

github-actions[bot] commented 3 years ago

Issue validator

The issue is valid!

lucasjohnston commented 3 years ago

@WoLewicki Is "modal" a specific construct in RNScreens (ie. the stackPresentation: 'modal' param) or do you mean modal in terms of general function / design? More context would be appreciated :) We aren't using the stackPresentation: 'modal' property anywhere and are not using modals, but might well be navigating between screens incorrectly. Happy to share our navigation config in more detail privately if useful.

I found that there was a bug in our state/store logic which was causing the crash. The issue went away once that was solved, but I have a feeling this RNScreens bug is still lurking in the background + am still unsure about why there was such a big difference in behaviour between Xcode + on device.

WoLewicki commented 3 years ago

By modal I meant all of RNScreens stackPresentation options different than push, so basically the native iOS modals used and handled by RNScreens, sorry for not communicating it clear enough.

I added some context in the description of #839, there might be a flow where you post new transitions during the ongoing transition, and it might result (and it does in the reproduction https://github.com/software-mansion/react-native-screens/issues/791#issuecomment-785701873) in pushing the same VC twice. It can occur if you use navigating as a response to events.

It is indeed weird that there could be difference when using Xcode.

Also, I think the structure of the navigation does not seem as a private configuration, and it would be best if it was available for everyone to test it and maybe find the solution, but if it is not possible for you for some reason, you can share it privately.

WoLewicki commented 3 years ago

I updated the #839 to a better solution (hopefully). I also added a test case where the crash could be reproduced each time without the native changes. Could you check if applying it fixes your issues?

micheleb commented 3 years ago

Hey there 👋🏻 Chipping in since I saw that @WoLewicki didn't get feedback on #839. I had the same issue, and applying your fix on top of my fork fixed it 🎉 Thanks!

charles-goode commented 2 years ago

I've recently started getting this same crash report on sentry. Unfortunately, I haven't been able to nail down which actions result in this crash (fairly large codebase and users haven't made coincident reports). We are on 3.8.0 (expo 43) and use hermes. We didn't have this issue before this version.

qilovehua commented 2 years ago

same issue everyday and no idea to reproduce it. "react": "17.0.2", "react-native": "0.66.4", "react-native-screens": "^3.10.1", "@react-navigation/bottom-tabs": "^6.0.9", "@react-navigation/native": "^6.0.6", "@react-navigation/native-stack": "^6.2.5",

chetan-sevaro commented 2 years ago

I am also facing the same issue and not able to reproduce it in debug mode

bmitioglov commented 1 year ago

I have installed latest version of react-native-screens and now it works, thanks

cooperwalter commented 1 year ago

@bmitioglov We're using the latest react-native-screens version (3.20.0), but we're still seeing this crash every day. Could you share your versions for react, react-native, and all react-navigation packages? I'm wondering if the crash arises from a certain combination of certain versions of these packages.

hdjvieira commented 1 year ago

Having the same issue, using latest react-native-screens version 3.20.0 and: react v18.2.0 react-native v0.71.1 @react-navigation/bottom-tabs v6.5.5 @react-navigation/drawer v6.6.0 @react-navigation/material-top-tabs v6.6.0 @react-navigation/native v6.1.4 @react-navigation/native-stack v6.9.10 Issue only happening in production, unable to reproduce it or fix it.

jordy-homerr commented 1 year ago

We too are experiencing those crashes and unable to figure out where they come from.

"react": "18.2.0", "react-native": "0.71.2", "react-native-screens": "3.0.0", "@react-native-google-signin/google-signin": "^9.0.2", "@react-navigation/bottom-tabs": "^6.5.2", "@react-navigation/material-top-tabs": "^6.5.1", "@react-navigation/native": "^6.1.1", "@react-navigation/stack": "^6.3.10",

hexadecy commented 1 month ago

We have this issue on iPhone 12 and more after 2 seconds of opening our Non-Fabric app.

Since we migrated from: react-native-screens 3.32.0 to 3.34.0 react-native 0.73.9 to 0.74.5 react-native-reanimated 3.14.0 to 3.15.2 @react-navigation/drawer 6.7.0 to 6.7.2 @react-navigation/native 6.1.17 to 6.1.18 @react-navigation/native-stack 6.10.0 to 6.11.0

I suspect this commit: https://github.com/software-mansion/react-native-screens/commit/68dabd93488da9c1c403039b9a89d5ac89471a97 in 3.33.0

When reverting to r-n-s 3.32.0, we no longer have the issue. I cannot reproduce it on iPhone 11, but we can on iPhone 14.

vorontsovanady commented 1 month ago

We still have this issue after upgrade RN screens from 3.29.0 to 3.32.0, reproduced this on iPad7,5 (iOS v17.5.1) "react-native-screens": "^3.32.0", "react-native": "0.73.7", "react": "18.2.0", "@react-navigation/bottom-tabs": "^6.5.16", "@react-navigation/drawer": "^6.6.11", "@react-navigation/elements": "^1.3.30", "@react-navigation/material-bottom-tabs": "^6.2.24", "@react-navigation/material-top-tabs": "^6.6.10", "@react-navigation/native": "^6.1.14", "@react-navigation/native-stack": "^6.9.22", "@react-navigation/stack": "^6.3.25",

hexadecy commented 1 month ago

@vorontsovanady what version of react-native-reanimated? There is a crash with the react-navigation-bottom-tabs: https://github.com/software-mansion/react-native-reanimated/issues/6222 It's fixed in r-n-reanimated 3.15.0

vorontsovanady commented 1 month ago

@hexadecy I don't have react-native-reanimated in the project

hexadecy commented 1 month ago

@vorontsovanady or maybe you should: https://reactnavigation.org/docs/upgrading-from-5.x/#drawer-now-uses-reanimated-2-if-available

There is a new implementation based on the latest Reanimated which will be used if it's available, otherwise drawer will fallback to the old implementation.

In drawer

"peerDependencies": {
  "react-native-reanimated": ">= 2.0.0"
}

From what I see in the code, it cannot use Drawer.native.tsx and Overlay.native.tsx without react-native-reanimated.

vorontsovanady commented 1 month ago

@hexadecy sounds like it could help me. Will try, thanks!

yahacom commented 3 weeks ago

I'm also faced this issue a few days ago. It's not always reproducible. But it should be related to switching between native stacks in my case I guess.

Libraries I use:

"react-native": "0.74.1",
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.9.26",
"react-native-screens": "^3.34.0",

Issue happens on iPhone 12 with iOS 17.6.1

I have divided my navigation into two parts: AuthNavigator and AppStack like this

<NavigationContainer ref={navigationRef} theme={navTheme} linking={linking}>
    {isAuth ? <AppStack /> : <AuthNavigator />}
</NavigationContainer>

Both AppStack and AuthNavigator represent Native Stack Navigators created by createNativeStackNavigator. Like:

const { Navigator, Screen } = createNativeStackNavigator();

return (
  <Navigator>
    <Screen .... />
    <Screen .... />
    <Screen .... />
  </Navigator>
);

Might it be I catch this issue because I have two native stack navigators change each other when isAuth changes?

crash report for reference ``` Fatal Exception: NSInvalidArgumentException is pushing the same view controller instance () more than once which is not supported and is most likely an error in the application Fatal Exception: NSInvalidArgumentException 0 CoreFoundation 0x83f20 __exceptionPreprocess 1 libobjc.A.dylib 0x172b8 objc_exception_throw 2 UIKitCore 0x3c03d8 -[UINavigationController pushViewController:transition:forceImmediate:] 3 UIKitCore 0xba5d8 -[_UIAfterCACommitBlock run] 4 UIKitCore 0xba49c -[_UIAfterCACommitQueue flush] 5 UIKitCore 0xba3b4 _runAfterCACommitDeferredBlocks 6 UIKitCore 0xb9fec _cleanUpAfterCAFlushAndRunDeferredBlocks 7 UIKitCore 0xb9efc _UIApplicationFlushCATransaction 8 UIKitCore 0xb7660 _UIUpdateSequenceRun 9 UIKitCore 0xb72a4 schedulerStepScheduledMainSection 10 UIKitCore 0xb8148 runloopSourceCallback 11 CoreFoundation 0x56834 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ 12 CoreFoundation 0x567c8 __CFRunLoopDoSource0 13 CoreFoundation 0x54298 __CFRunLoopDoSources0 14 CoreFoundation 0x53484 __CFRunLoopRun 15 CoreFoundation 0x52cd8 CFRunLoopRunSpecific 16 GraphicsServices 0x11a8 GSEventRunModal 17 UIKitCore 0x40aae8 -[UIApplication _run] 18 UIKitCore 0x4bed98 UIApplicationMain 19 Application Name 0x1c698 main + 20 (main.m:20) 20 ??? 0x1c1e9f154 (Missing) ```
a389216 commented 1 week ago

@WoLewicki could you reopen this issue ? Is still present in latest RNS version.

WoLewicki commented 1 week ago

Since it is an issue from deep deep past, could you open another issue with a reproduction of the problem so we could work on it?