skip to Main Content

I am trying to authenticate a user using biometrics and pin on my app and I am trying to pass states to the PinSreen. But I am getting an error

Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a Symbol.iteratormethod.

Here is my APP.js

import { AuthContext } from './contexts/AuthContext';

const Stack = createStackNavigator();

const theme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    background: "transparent",
  },
};

const App = () => {
  const [onboarded, setOnboarded] = useState(false);
  const [authenticated, setAuthenticated] = useState(false);

  useEffect(() => {
    getStorage();
  }, []);

  const getStorage = async () => {
    const onboarded = await AsyncStorage.getItem('@onboarded');
    setOnboarded(JSON.parse(onboarded));
  };

  const [loaded] = useFonts({
    SFBold: require("./assets/fonts/sf-bold.ttf"),
    SFMedium: require("./assets/fonts/sf-medium.ttf"),
    SFRegular: require("./assets/fonts/sf-regular.ttf"),
    SFLight: require("./assets/fonts/sf-light.ttf"),
  });
  if (!loaded) return null;

  return (
    <AuthContext.Provider value={{ authenticated, setAuthenticated }}>
      <NavigationContainer theme={theme} >
        <Stack.Navigator initialRouteName={!onboarded ? 'Onboarding' : !authenticated ? 'PinScreen' : 'BottomBar'} screenOptions={{ headerShown: false }}>
          <Stack.Screen name="BottomBar" component={BottomBar} />
          <Stack.Screen name="PinScreen" component={PinScreen} />
          <Stack.Screen name="Onboarding" component={Onboarding} />
          <Stack.Screen name="CodeScanner" component={CodeScanner} />
          <Stack.Screen name="SignUp" component={SignUp} />
          <Stack.Screen name="SignIn" component={SignIn} />
          <Stack.Group screenOptions={{ presentation: 'modal' }}>
            <Stack.Screen name="Deposit" component={Deposit} />
            <Stack.Screen name="Authorise" component={Authorise} />
          </Stack.Group>
        </Stack.Navigator>
      </NavigationContainer>
    </AuthContext.Provider>
  );
}

export default App;

And here is my PinScreen where after the pin biometrics are input correctly, the setAuthenticated(true); is set

const PinScreen = () => {

    const navigation = useNavigation();

    const [pin, setPin] = useState('');
    const [authenticated, setAuthenticated] = useContext(AuthContext);
    const [isBiometricSupported, setIsBiometricSupported] = useState(false);
    const [isPinSet, setIsPinSet] = useState(false);
    const [error, setError] = useState(false);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        (async () => {
            const compatible = await LocalAuthentication.hasHardwareAsync();
            setIsBiometricSupported(compatible);
        })();
    });

    const handleButtonPress = (value) => {
        if (pin.length < 6) {
            setPin(pin + value);
        }
    }
    function onAuthenticate() {
        LocalAuthentication.authenticateAsync().then(auth => {
            if (auth.success) {
                setAuthenticated(true);
                setLoading(true);
                setTimeout(() => {
                    navigation.navigate('BottomBar', { screen: 'Home' });
                }, 800);
            } else {
                setError(true);
                Vibration.vibrate(200);
            }
        });
    }

Why am I getting the error. Why is it not working? Please help

2

Answers


  1. When you’re passing the authenticated and setAuthenticated to your AuthContext.Provider, you pass it as a object {}.

    <AuthContext.Provider value={{ authenticated, setAuthenticated }}>
    

    Then in your PinScreen you try to desctructure it as a array []

    const [authenticated, setAuthenticated] = useContext(AuthContext);
    

    Instead you should destructure it as a object

    const { authenticated, setAuthenticated } = useContext(AuthContext);
    
    Login or Signup to reply.
  2. Your error seems to be here in PinScreen.js:

    const [authenticated, setAuthenticated] = useContext(AuthContext);
    

    You are trying to destructure an array that is actually an object.:

    <AuthContext.Provider value={{ signed: true, Login }}>
    

    Try the following change in PinScreen.js:

    const { authenticated, setAuthenticated } = useContext(AuthContext);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search