pendo-io / pendo-mobile-sdk

Pendo captures product usage data, gathers user feedback, and lets you communicate in-app to onboard, educate, and guide users to value
https://www.pendo.io
Other
59 stars 2 forks source link

Navigation resets when appState is 'background' #189

Closed shalkauskas closed 1 month ago

shalkauskas commented 1 month ago

Platform + Version IOS 18, Android

SDK Version 3.1.1 3.4.0

Framework React Native using React Navigation

Describe the bug When appState is changed from 'active' to 'background', navigation immediately reset to initialRoute. For example, when app opens camera or gallery to select a picture, navigation resets to initial route. Replacing PendoNavigationContainer with NavigationContainer from @react-navigation solves the issue. Happens on all Android versions and devices, but only sometimes on iOS (when app asks for permissions to use camera/gallery). Minimizing the app resets the navigation as well. First noticed on SDK 3.1.1. Updated to latest 3.4.0, but issue remains. Also after updating, console returns a warning:

WithPendoReactNavigation was called more than once. Please make sure you only call WithPendoReactNavigation once in the application lifecycle.

Expected behavior Navigation state does not reset on appState changes.

Logs Log on 3.1.1

 DEBUG  [rn-pendo-sdk]  analyzeTree - screenId: AddAttachment
 DEBUG  [rn-pendo-sdk]  Pendo Plugin 3.1.2, React Native: 0.74.1
 INFO  [rn-pendo-sdk]  React Navigation Init.
 DEBUG  [rn-pendo-sdk]  WithPendoReactNavigation was called
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onDynamicContentRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onCaptureRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onReturnFromAlertRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onDefaultRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onScreenContentChange
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onModalStateVisible
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onModalStateHidden
 DEBUG  [rn-pendo-sdk]  PNDContainer onReady
 DEBUG  [rn-pendo-sdk]  traverseOnComponent entry
 DEBUG  [rn-pendo-sdk]  Candidates for Navigation BarNode: navigationcontent, Parent: 197, Child: 3559
 DEBUG  [rn-pendo-sdk]  Candidates for Navigation BarNode: headercontainer, Parent: 3555, Child: 3553
 DEBUG  [rn-pendo-sdk]  NavigationBar discovered:  3555
 DEBUG  [rn-pendo-sdk]  Candidates for Navigation BarNode: headercontainer, Parent: 3535, Child: 3533
 DEBUG  [rn-pendo-sdk]  NavigationBar discovered:  3535
 DEBUG  [rn-pendo-sdk]  Candidates for Navigation BarNode: navigationcontent, Parent: 3529, Child: 3527
 DEBUG  [rn-pendo-sdk]  Root Tag discovered:  3473
 DEBUG  [rn-pendo-sdk]  Root Tag discovered:  3475
 DEBUG  [rn-pendo-sdk]  Root Tag discovered:  3327
 DEBUG  [rn-pendo-sdk]  Root Tag discovered:  3329
 DEBUG  [rn-pendo-sdk]  Root Tag discovered:  3317
 DEBUG  [rn-pendo-sdk]  Root Tag discovered:  3319
 DEBUG  [rn-pendo-sdk]  Candidates for Navigation BarNode: generalheader, Parent: 3319, Child: 3317
 DEBUG  [rn-pendo-sdk]  analyzeTree - screenId: DailyAssignments

Log on SDK 3.4.0

 DEBUG  [rn-pendo-sdk]  analyzeTree - screenId: AddAttachment
 DEBUG  [rn-pendo-sdk]  Pendo Plugin 3.4.0, React Native: 0.74.1
 INFO  [rn-pendo-sdk]  React Navigation Init.
 WARN  [rn-pendo-sdk]  WithPendoReactNavigation was called more than once. Please make sure you only call WithPendoReactNavigation once in the application lifecycle. {} 
    at NavigationSetup (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:170576:36)
    at $29383e587d62412a$export$9f8ac96af4b1b2ae (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:246804:43)
    at ToastProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:262204:25)
    at PortalProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:252204:50)
    at HybridProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:266835:24)
    at ResponsiveQueryProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:233024:14)
    at RNCSafeAreaProvider
    at SafeAreaProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:233650:24)
    at NativeBaseConfigProviderProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:217630:27)
    at NativeBaseProvider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:266767:33)
    at PersistGate (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:440709:22)
    at Provider (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:332377:21)
    at App (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:169800:38)
    at RCTView
    at View (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:64865:43)
    at RCTView
    at View (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:64865:43)
    at AppContainer (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:64737:25)
    at MobileApp(RootComponent) (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.operix.apptest&modulesOnly=false&runModule=true:118396:28)
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onDynamicContentRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onCaptureRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onReturnFromAlertRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onDefaultRequestAnalyzer
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onScreenContentChange
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onModalStateVisible
 DEBUG  [rn-pendo-sdk]  addScanRequestListener: onModalStateHidden
 DEBUG  [rn-pendo-sdk]  PNDContainer onReady

Sample Code NavigationSetup.js

const NavigationSetup = () => {
  const routeNameRef = React.useRef();
  const PendoNavigationContainer =
    WithPendoReactNavigation(NavigationContainer);
  return (
    <React.Fragment>
      <PendoNavigationContainer>
        <RootNavigation />
      </PendoNavigationContainer>
    </React.Fragment>
  );
};

Navigation setup in App.js

 <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <SplitContext.Provider value={splitValue}>
          <NetworkProvider />
          <NativeBaseProvider theme={nativeBaseThemeSetup}>
            <NavigationSetup />
          </NativeBaseProvider>
        </SplitContext.Provider>
      </PersistGate>
    </Provider>**
udilevin commented 1 month ago

Please move

const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer);

To a global scope so it won't be executed every time the component is rendered.

shalkauskas commented 1 month ago

Moving PendoNavigationContainer to App.js did not help, but wrapping it in React.useMemo to avoid re-execution did solve the issue with both console warning and navigation reset, thanks @udilevin