본문 바로가기

React-Native

[RN] Expo54버전 채널톡 연동 NOT_INITIALIZED 이슈

Expo 54버전에서 RN에 채널톡을 연동하기 위해 

 "@peulda/expo-plugin-channel-io": "^1.1.0",
 "react-native-channel-plugin": "^0.12.5",

 이렇게 두 개의 모듈을 설치해줬다.

이후 https://desk.channel.io/

 

채널톡

 

desk.channel.io

에서 계정 생성 후 채널을 만들어주었다.

일반 설정 -> 버튼 설치 및 설정에서 Plugin Key를 확인해주었고 .env 및 expo 웹의 환경변수에 플러그인 키를 셋팅해주었다.

export function ChannelProvider({ children }: { children: ReactNode }) {
  const isAuthenticated = useUserStore((state) => state.isAuthenticated);
  const user = useUserStore((state) => state.user);
  useEffect(() => {
    if (!isAuthenticated || !user) {
      ChannelIO.shutdown();
      return;
    }

    const pluginKey = env.CHANNEL_IO_PLUGIN_KEY;

    if (!pluginKey) {
      console.warn("CHANNEL_IO_PLUGIN_KEY가 설정되지 않았습니다.");
      return;
    }
    ChannelIO.setDebugMode(true); // 네이티브 로그도 더 많이 찍혀요.

    ChannelIO.boot({
      pluginKey,
      memberId: user?.id,
      profile: {
        name: user?.identifier,
        email: user?.email,
      },
      language: "ko",
    })
      .then((result) => {
        console.log(
          "ChannelIO boot callback status:",
          result.status,
          "user:",
          result
        );
      })
      .catch((e) => {
        console.error("ChannelIO boot 실패", e);
      });

    return () => {
      ChannelIO.shutdown();
    };
  }, [user?.id, isAuthenticated]);

  return <>{children}</>;
}


앱을 감싸는 진입지점 EntryPoint에서 위와 같이 Provider를 만들어주고 채널톡을 boot했으니, 이상하게도 따로 에러가 나진 않는데, 부트가 안되고있었다...

boot 이후 결과를 찍어보니, 결과는 status:NOT_INITIALIZED였다. 

플러그인 키의 문제가 아니였고, app.config.js에서도

    plugins: [
        "@peulda/expo-plugin-channel-io",
        [
          "expo-splash-screen",
          {
            backgroundColor: "#000000",
            image: "./src/app/assets/splash_image.png",
            // dark: {
            //   image: "./assets/splash-icon-dark.png",
            //   backgroundColor: "#000000",
            // },
            imageWidth: 140,
          },
        ],
        [
          "expo-image-picker",
          {
            cameraPermission:
              "카메라로 사진을 촬영하기 위해 권한이 필요합니다.",
            photosPermission:
              "앨범에서 사진을 선택하기 위해 권한이 필요합니다.",
          },
        ],
      ],

위와 같이

 "@peulda/expo-plugin-channel-io",


모듈을 잘 연결했다.

prebuild --clean, ios, android 재빌드도 실행했는데 초기화가 안되는 문제의 원인을 찾아보았다.

 

예상가는 문제는 Expo 54 + New Architecture 때문에 플러그인 패치가 안 먹는 케이스였다.

@peulda/expo-plugin-channel-io는 README에서 Expo SDK 48에서 테스트됐다고 명시가 되어있다.

Expo SDK 54(RN 0.81)라서 플러그인이 AppDelegate/MainApplication 패치를 제대로 못 했을 가능성이 커보였다.

우선 app.config.js에서 newArchEnabled의 값을 false로 두고 다시 prebuild --clean을 해보았다. 

버전 호환 문제가 맞아 @peulda/expo-plugin-channel-io를 제거한 뒤 

채널톡 공식 가이드 문서를 보며 직접 ios, android에 initialize 코드를 주입해주었다.

우선 android일 경우 build.gradle에서 buildscript -> repositories 안에

    maven {
      url 'https://maven.channel.io/maven2'
      name 'ChannelTalk'
    }

를 추가해준다.
이후 초기화를 진행해주어야 한다.
MainApplication.kt 파일을 찾아준다.

onCreate 함수 안에

    ChannelIO.initialize(this)

를 한 줄 추가해주면 안드로이드에서의 초기화는 끝난다.

IOS의 경우 AppDelegate.swift 파일을 찾는다.

import ChannelIOFront


모듈을 import해준 뒤,

  public override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    let delegate = ReactNativeDelegate()
    let factory = ExpoReactNativeFactory(delegate: delegate)
    delegate.dependencyProvider = RCTAppDependencyProvider()

    reactNativeDelegate = delegate
    reactNativeFactory = factory
    bindReactNativeFactory(factory)
    ChannelIO.initialize(application)

#if os(iOS) || os(tvOS)
    window = UIWindow(frame: UIScreen.main.bounds)
    factory.startReactNative(
      withModuleName: "main",
      in: window,
      launchOptions: launchOptions)
#endif

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }


didFinishLaunchingWithOptions가 있는 application 함수에 return 하기 전 

    ChannelIO.initialize(application)

한 줄을 추가해주면 초기화가 진행된다.


이후 정상적으로 Initialize가 실행된 것을 확인할 수 있었다.

개인적으로 Expo환경에서도 채널톡 공식 문서 가이드대로 ios, android에 직접 주입해서 초기화 하는 방법이 더 안정적이고 좋은 것 같다. :)





+12월 22일 수정
prebuild --clean시 위에 작성한 스크립트가 모두 초기화되어,
프로젝트 최상단에 withChannelTalk.js 스크립트를 만들어주었다. (위 코드들을 prebuild시점에 네이티브 파일에 주입하는 파일)

이후 app.config.js에서 

   plugins: [
        "./plugins/withChannelTalk",
        [
          "expo-splash-screen",

만들어준 파일을 플러그인으로 삽입해 prebuild시점에 채널톡 코드를 주입시켜주어 해결할 수 있었다.