React Native - Switching to other Screen after Permission Granted

So I have 2 screens, the SplashScreen.js and the Auth.js. In the SplashScreen.js is were all the Permissions Android run and if it is granted it will navigate it to the AuthScreen.js.

But in my case, after it granted the app crashes. I just don't know why.

So what I want to happen is, after the Permission Android granted it will navigate it to the AuthScreen.js.

Here are my codes:

SplashScreen.js: This is inside the class SplashScreen extendes Component {}

constructor(props) {
super(props);

this.state = {
  timePassed: false
};
}

componentDidMount() {
this.permissionAndroid();
};

setTimePassed() {
this.setState({timePassed: true})
};

permissionAndroid = () => {
try {
  const granted = PermissionsAndroid.requestMultiple(
    [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE],
    {
      title: "Location Permission",
      message: "You have to, because it's a party app! " + "So you can enjoy more viewing events.",
      buttonNeutral: "Ask me later",
      buttonNegative: "Cancel",
      buttonPositive: "OK"
    },
  );
  if (granted == PermissionsAndroid.RESULTS.GRANTED) {
    console.log("All permision enabledenabled")
    // this.setTimePassed();
    this.setState({timePassed: true})
  } else {
    console.log('Location Permission Denied');
  }
} catch (err) {
  console.warn(err);
}
}

render() {
if(!this.state.timePassed) {
  return (
    <View style={styles.container}>
      <Text>Hello</Text>
    </View>
  );
} else {
  return <AuthScreen/>
}
};

I also have the code of Permission Android outside the Class with async function, I didn't use this right now because this.setState({}) or function setTimePassed() will not work I think because it is outside the Class.

This is another option to make app works, but I'm just not sure how the setState({}) or the setTimePassed() will work when it pass outside the Class.

This code is in the SplashScreen.js also: (it is also same with the function permissionAndroid it just have a async function)

async function requestLocationPermission() {
try {
const granted = await PermissionsAndroid.requestMultiple(
  [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE],
  {
    title: "Location Permission",
    message: "You have to, because it's a party app! " + "So you can enjoy more viewing events.",
    buttonNeutral: "Ask me later",
    buttonNegative: "Cancel",
    buttonPositive: "OK"
  },
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
  console.log("All permision enabledenabled")
  // setTimePassed();
  this.setState({
    timePassed: true
  });
} else {
  console.log('Location Permission Denied');
}
} catch (err) {
  console.warn(err);
}
}

2 answers

  • answered 2019-07-18 15:46 Yanick Bélanger

    You should start off by marking permissionAndroid as async because it is an asynchronous function and use await. I've checked the React Native docs and they state that PermissionsAndroid.requestMultiple() :

    "Prompts the user to enable multiple permissions in the same dialog and returns an object with the permissions as keys and strings as values (see result strings above) indicating whether the user allowed or denied the request or does not want to be asked again."

    So this function does not return a boolean like PermissionsAndroid.request(), but rather an array with the following structure :

    const granted = PermissionsAndroid.requestMultiple(
        [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE],
        {
          title: "Location Permission",
          message: "You have to, because it's a party app! " + "So you can enjoy more viewing events.",
          buttonNeutral: "Ask me later",
          buttonNegative: "Cancel",
          buttonPositive: "OK"
        }
    );
    
    console.log(granted); // { PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION : true, PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE : false }
    

    As for requestLocationPermission, you're right : you can't call setState outside of a Component class. You could use callbacks as arguments in which you would perform the required actions for the two scenarios (granted and denied). Or you could simply move the code into the class.

    @dimonD is right, you should use a navigation framework such as React Navigation or React Native Navigation.

  • answered 2019-07-18 15:46 dimonD

    I think you need to use some navigation, for example reactnavigation.org. After user permission is granted, you simple do

    navigation.navigate("Screen you want to show")

    Also is a some concept for auth flow, where you can implement what should happen before/after user get a LoginScreen.
    You can check it here https://reactnavigation.org/docs/en/auth-flow.html