kanzitelli / rnn-starter

🤹 React Native Starter - Powered by cli-rn, React Native Navigation, Expo Modules, RNN Screens, RN UI lib, MMKV, Mobx, Reanimated 2, Dark Mode, Splash Screen, Localization, Notifications, Permissions, and much more.
https://starters.dev
MIT License
551 stars 72 forks source link

App wouldn't start with old code structure. #98

Closed Yasir5247 closed 2 years ago

Yasir5247 commented 2 years ago

Hi, @kanzitelli you have saved me from lot of troubles and i'm very grateful to u. Thank you for maintaining this starter kit. Here is my problem. After upgrading to the latest changes i can't use this old following code structure. if i convert the old way to new way using 'rnn-screens' it works. but i have huge code base and conversion to 'rnn-screens' is not option for me right now. is there anyway i can run the app with the old following structure?

The error message says:

Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native., js engine: hermes

Possible Unhandled Promise Rejection (id: 0): TypeError: Cannot read property 'screens' of undefined TypeError: Cannot read property 'screens' of undefined

index.js

import 'react-native-gesture-handler';
import { Navigation } from 'react-native-navigation';
import { start } from './src/app';

Navigation.events().registerAppLaunchedListener(start);

./src/app


import {hydrateStores} from './stores';
import {initServices, services} from './services';
import {configureDesignSystem} from './utils/designSystem';

export const start = async (): PVoid => {
  const {nav, Noti} = services;

  // 1. hydrate stores
  await hydrateStores();

  // 2. configure design system
  configureDesignSystem();

  // 3. init services
  await initServices();

  // 4. start app
  nav.start();
};

./src/services/navigation/index.ts

start = async (): PVoid => {
    const token = await AsyncStorage.getItem('@token');
    token ? await this.startThreeTabsApp() : await this.startOneScreenApp();
    await this.getConstants(); // needs to be called after setRoot()
  };

private startOneScreenApp = async (): PVoid => {
    await Navigation.setRoot(Root(Stack(Component(screensLayouts.ScreenOne))));
  };

  private startThreeTabsApp = async (): PVoid => {
    await Navigation.setRoot(
      Root(
        BottomTabs([
          Stack(Component(screensLayouts.HomeScreen)),
          Stack(Component(screensLayouts.ScanScreen)),
          Stack(Component(screensLayouts.MailScreen)),
        ]),
      ),
    );
  };
kanzitelli commented 2 years ago

Hi @Yasir5247! Great to hear that it helped you!

Regarding the error, it seems like that ‘screens’ are being used somewhere in the code base. What i would recommend is to remove ‘rnn-screens’ completely from the project, and just copy code manually for ‘Root’, ‘Component’, etc. from the library. Maybe it’ll help. And also run ‘yarn start’ with ‘--reset-cache’ option, just in case.

Let me know how it goes!

Yasir5247 commented 2 years ago

Hi, @kanzitelli i'm not sure if followed you there. "and just copy code manually for ‘Root’, ‘Component’, etc. from the library."

kanzitelli commented 2 years ago

@Yasir5247 i meant just to take the code from here — https://github.com/kanzitelli/rnn-screens/blob/main/src/layouts.tsx. Because i’ve seen in the code that you are using them

Yasir5247 commented 2 years ago

i'm not sure if there's any difference.

/src/services/navigation/layouts.ts

import {
  Options,
  Layout,
  LayoutStackChildren,
  LayoutRoot,
  LayoutTabsChildren,
  LayoutComponent,
} from 'react-native-navigation';

// Set of methods which help building RNN layout without long boring code like {stack:component:{...}}

const Root = (root: Layout): LayoutRoot => ({root});

const BottomTabs = (children?: LayoutTabsChildren[], options?: Options): Layout => ({
  bottomTabs: {children, options},
});

const StackMany = (children?: LayoutStackChildren[], options?: Options): Layout => ({
  stack: {children, options},
});

const Stack = (c: LayoutStackChildren, options?: Options): Layout => StackMany([c], options);

const Component = <P>(component: LayoutComponent<P>): Layout => ({component});

export {Root, BottomTabs, Stack, StackMany, Component};

/src/services/navigation/index.ts

import {Constants, Navigation, NavigationConstants, Options} from 'react-native-navigation';
import {gestureHandlerRootHOC as withGestureHandler} from 'react-native-gesture-handler';
import pipe from 'lodash/flowRight';
import AsyncStorage from '@react-native-async-storage/async-storage';

import {Screen, screens, screensLayouts} from '../../screens';
import {withStores} from '../../stores';
import {services, withServices} from '../../services';
import {withClient} from '../../services/client';

import {configureDesignSystem} from '../../utils/designSystem';
import {BottomTabs, Component, Root, Stack} from './layout';
import {navDefaultOptions} from './options';

export class Nav implements IService {
  private inited = false;
  private N = Navigation;
  // nav constants always updated on willAppear event
  C: NavigationConstants = Constants.getSync();

  init = async (): PVoid => {
    if (!this.inited) {
      await this.registerScreens();
      this.setDefaultOptions();
      this.registerListeners();
      this.inited = true;
    }
  };

  // Start different apps' logic
  start = async (): PVoid => {
    const token = await AsyncStorage.getItem('@token');
    token ? await this.startThreeTabsApp() : await this.startOneScreenApp();
    await this.getConstants(); // needs to be called after setRoot()
  };

  restart = async (): PVoid => {
    this.setDefaultOptions(); // settings navigation options
    configureDesignSystem(); // configuring design system with updated appearance
    services.t.setup(); // setting up new language for translation service
    await this.start();
  };

  private startOneScreenApp = async (): PVoid => {
    await Navigation.setRoot(Root(Stack(Component(screensLayouts.ScreenOne))));
  };

  private startThreeTabsApp = async (): PVoid => {
    await Navigation.setRoot(
      Root(
        BottomTabs([
          Stack(Component(screensLayouts.HomeScreen)),
          Stack(Component(screensLayouts.ScanScreen)),
          Stack(Component(screensLayouts.MailScreen)),
        ]),
      ),
    );
  };

  // Navigation methods
  push = async <T>(cId: string, name: Screen, passProps?: T, options?: Options): PVoid => {
    const sl = screensLayouts[name];

    await this.N.push(
      cId,
      Component({
        ...sl,
        passProps,
        options: {
          ...sl.options,
          ...options,
        },
      }),
    );
  };

  pop = async (cId: string): PVoid => {
    this.N.pop(cId);
  };

  popToRoot = async (cId: string): PVoid => {
    this.N.popToRoot(cId);
  };

  show = async <T>(name: Screen, passProps?: T, options?: Options): PVoid => {
    const sl = screensLayouts[name];
    this.N.showModal(
      Stack(
        Component({
          ...sl,
          passProps,
          options: {
            ...sl.options,
            ...options,
          },
        }),
      ),
    );
  };

  showOverLay = async <T>(name: Screen, passProps?: T, options?: Options): PVoid => {
    const sl = screensLayouts[name];

    await this.N.showOverlay(
      Component({
        ...sl,
        passProps,
        options: {
          ...sl.options,
          ...options,
        },
      }),
    );
  };

  private setDefaultOptions = (): void => {
    this.N.setDefaultOptions(navDefaultOptions());
  };

  // System methods
  private registerScreens = async () => {
    screens.forEach(s =>
      this.N.registerComponent(
        s.name,
        pipe(withClient, withGestureHandler, withStores, withServices, () => s.component),
        () => s.component,
      ),
    );
  };

  private registerListeners = () => {
    this.N.events().registerComponentWillAppearListener(() => {
      this.getConstants();
    });
  };

  private getConstants = async () => {
    this.C = Constants.getSync();
  };
}
kanzitelli commented 2 years ago

@Yasir5247 yeah, the main point of doing that is to remove rnn-screens completely from your project. Because the error says that you are referring to ‘screens’.

Does it show any error now?

Yasir5247 commented 2 years ago

@kanzitelli removed 'rnn-screens' completely and cleaned the project using 'react-native-clean-project' package. and it worked. i didn't changed anything related to pervious version of navigation handling. thank you for the help. :)

kanzitelli commented 2 years ago

@Yasir5247 great to hear! probably it was a cache error or something. then I'm closing the issue.

Yasir5247 commented 2 years ago

@kanzitelli sorry to trouble you. but i have trouble in android build.

After gradle sync

CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
FBJNI_LIB
linked by target "expo-modules-core" in directory /Users/pmu/Documents/Office/Efaas/node_modules/expo-modules-core/android
FOLLY_LIB
linked by target "expo-modules-core" in directory /Users/pmu/Documents/Office/Efaas/node_modules/expo-modules-core/android
JSI_LIB
linked by target "expo-modules-core" in directory /Users/pmu/Documents/Office/Efaas/node_modules/expo-modules-core/android
REACT_NATIVE_JNI_LIB
linked by target "expo-modules-core" in directory /Users/pmu/Documents/Office/Efaas/node_modules/expo-modules-core/android
REACT_NATIVE_MODULES_CORE
linked by target "expo-modules-core" in directory /Users/pmu/Documents/Office/Efaas/node_modules/expo-modules-core/android

Expo EAS

eas build --platform android --profile preview

[stderr] FAILURE:
[stderr] Build failed with an exception.
[stderr] * Where:
[stderr] Build file '/home/expo/workingdir/build/node_modules/react-native-navigation/lib/android/app/build.gradle' line: 177
[stderr] * What went wrong:
[stderr] A problem occurred evaluating project ':react-native-navigation'.
[stderr] > Cannot run program "/home/expo/Android/Sdk/cmdline-tools/latest/bin/sdkmanager": error=2, No such file or directory
[stderr] * Try:
[stderr] > Run with --stacktrace option to get the stack trace.
[stderr] > Run with --info or --debug option to get more log output.
[stderr] > Run with --scan to get full insights.
[stderr] * Get more help at https://help.gradle.org
[stderr] BUILD FAILED in 1m 46s
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
See https://docs.gradle.org/7.3.3/userguide/command_line_interface.html#sec:command_line_warnings
6 actionable tasks: 6 executed
Unable to list file systems to check whether they can be watched. The whole state of the virtual file system has been discarded. Reason: Could not query file systems: could not open mount file (errno 2: No such file or directory)
Error: Gradle build failed with unknown error. See logs for the "Run gradlew" phase for more information.
kanzitelli commented 2 years ago

@Yasir5247 I was not experiencing issues with CMake but I have seen it's happening to people. Probably it will be fixed in RN 0.70 as they moved to CMake by default. Try checking this - https://github.com/mrousavy/react-native-vision-camera/issues/588#issuecomment-972589478.

And the second issue happens because sdkmanager is not installed. You can install it through Android Studio. https://stackoverflow.com/questions/68236007/i-am-getting-error-cmdline-tools-component-is-missing-after-installing-flutter

Yasir5247 commented 2 years ago

@kanzitelli for the second question. trust me i tried every way before coming to you. also i have gone through that link and installed cmdline-tools.

its installed into my computer path ../Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager

my .zshrc profile

export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH="/usr/local/opt/openjdk@11/bin:$PATH"

Cannot run program "/home/expo/Android/Sdk/cmdline-tools/latest/bin/sdkmanager"

same error. ios builds good though.

any suggestions.


efaas-mobile-latest git:(develop) ✗ npx @react-native-community/cli doctor
warn Package react-native-navigation contains invalid configuration: "dependency.assets" is not allowed,"dependency.hooks" is not allowed. Please verify it's properly linked using "react-native config" command and contact the package maintainers about this.
warn Package react-native-ui-lib contains invalid configuration: "dependency.platforms.ios.project" is not allowed. Please verify it's properly linked using "react-native config" command and contact the package maintainers about this.
⠼ Running diagnostics...warn Package react-native-navigation contains invalid configuration: "dependency.assets" is not allowed,"dependency.hooks" is not allowed. Please verify it's properly linked using "react-native config" command and contact the package maintainers about this.
warn Package react-native-ui-lib contains invalid configuration: "dependency.platforms.ios.project" is not allowed. Please verify it's properly linked using "react-native config" command and contact the package maintainers about this.
Common
 ✓ Node.js
 ✓ yarn
 ✓ Watchman - Used for watching changes in the filesystem when in development mode

Android
 ✓ JDK
 ✓ Android Studio - Required for building and installing your app on Android
 ✓ Android SDK - Required for building and installing your app on Android
 ✓ ANDROID_HOME

iOS
 ✓ Xcode - Required for building and installing your app on iOS
 ✓ CocoaPods - Required for installing iOS dependencies
 ● ios-deploy - Required for installing your app on a physical device with the CLI
 ✓ .xcode.env - File to customize Xcode environment

Errors:   0
Warnings: 1

Usage
 › Press f to try to fix issues.
 › Press e to try to fix errors.
 › Press w to try to fix warnings.
 › Press Enter to exit.

➜  ~ which android
/Users/yasir/Library/Android/sdk/tools/android

Screenshot 2022-09-20 at 14 28 54

kanzitelli commented 2 years ago

Hi @Yasir5247! Well, it looks like you've done everything correct, but the script still can not be run because of the wrong directory. As I remember, this error Cannot run program "/home/expo/Android/Sdk/cmdline-tools/latest/bin/sdkmanager" comes from React Native Navigation app's build.gradle file. You can check it here - https://github.com/wix/react-native-navigation/blob/master/lib/android/app/build.gradle#L176. What I would recommend is to change that directory manually to yours from node_modules of your project. And if that works, just create a patch file which will change it.