launchdarkly/react-native-client-sdk

await client.identify never return. App crash when I remove await

Closed this issue · 5 comments

Describe the bug
I call "await client.identify({ key: userId, name: userName });" code and it never return back. The app will crash after I removed await, just run "client.identify({ key: userId, name: userName });"

The full code as below:

import { environmentConfig } from "@app/config/apiConfig";
import LDClient from "launchdarkly-react-native-client-sdk";
import React, { useContext, useEffect, useState } from "react";
import { Subject } from "rxjs";

const client = new LDClient();
const config = { mobileKey: environmentConfig.launchDarklyKey };

const LaunchDarklyContext = React.createContext<LDClient>(null);
const LaunchDarklyProvider = LaunchDarklyContext.Provider;

const flagChangedSubject = new Subject<string[]>();
let currentRegisterId = "";

export const WithLaunchDarklyProvider = React.memo(({ children }: { children: JSX.Element }) => {
  const [isInitilized, setIsInitilized] = useState(false);
  useEffect(() => {
    if (!client.isInitialized) {
      client.configure(config, { key: "Anonymous" }).then(() => {
        setIsInitilized(true);
        client.registerAllFlagsListener("anonymousListener", (flagKeys: string[]) => {
          flagChangedSubject.next(flagKeys);
        });
        currentRegisterId = "anonymousListener";
      });
    }
  }, []);

  return <LaunchDarklyProvider value={isInitilized ? client : null}>{children}</LaunchDarklyProvider>;
});

export const useLaunchDarklyFlag = (flagName: string): boolean | null => {
  const [flagValue, setFlagValue] = useState<boolean | null>(null);
  const ldClient = useContext(LaunchDarklyContext);
  useEffect(() => {
    if (ldClient) {
      ldClient.boolVariation(flagName, false).then(value => {
        setFlagValue(value);
      });
    }
  }, [ldClient, flagName]);
  useEffect(() => {
    const handler = flagChangedSubject.subscribe((flagKeys: string[]) => {
      console.info("=========================1", flagKeys);
      if (flagKeys.indexOf(flagName) >= 0) {
        ldClient.boolVariation(flagName, false).then(value => {
          setFlagValue(value);
          console.info("=========================2", flagName, value);
        });
      }
    });
    return handler.unsubscribe();
  }, [flagName]);

  return flagValue;
};
const identifyUser = async (userId: string, userName: string) => {
  if (currentRegisterId) {
    client.unregisterAllFlagsListener(currentRegisterId);
    currentRegisterId = "";
  }
  console.info("=========================7", userId, userName);
  try {
    await client.identify({ key: userId, name: userName });
    console.info("=========================4", userId, userName);
    client.registerAllFlagsListener(userId, (flagKeys: string[]) => {
      console.info("=========================3", flagKeys);
      flagChangedSubject.next(flagKeys);
    });
    currentRegisterId = userId;
  } catch (e) {
    console.info("=========================8", userId, userName);
  }
};
export const setLaunchDarklyUser = async (userId: string, userName: string) => {
  if (client.isInitialized) {
    console.info("=========================5", userId, userName);
    identifyUser(userId, userName);
  } else {
    setTimeout(async () => {
      console.info("=========================6", userId, userName);
      identifyUser(userId, userName);
    }, 500);
  }
};

OS/platform
React native, iOS

I think the crash caused by LDClient.get(environment: environment)

@objc func boolVariation(_ flagKey: String, defaultValue: ObjCBool, environment: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      resolve(LDClient.get(environment: environment)!.boolVariation(forKey: flagKey, defaultValue: defaultValue.boolValue))
  }

Thread 4: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Hello @robert-luoqing, thank you for reporting this issue to us. We have multiple reports about the force unwrapping issue in RN (with iOS) and are working on a fix for it.

Filed internally as 169352

@louis-launchdarkly Which version includes the fixed code? How can I use the fixed package? I want to integrate it into my project.

Thanks

Hello @robertstar10, sorry for the late reply as the team was chasing down the U2C context support and RN 0.71 support. We reworked the wrapper code for RN 7.x SDK release and removed all the forced unwrapping. Please let us know does the RN 7.x SDK fixes the issue for you.

This was also fixed in https://github.com/launchdarkly/react-native-client-sdk/releases/tag/6.3.1 if you are not ready for upgrading yet.