Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PermissionsAndroid.request never resolves #17985

Closed
jgfidelis opened this issue Feb 14, 2018 · 40 comments
Closed

PermissionsAndroid.request never resolves #17985

jgfidelis opened this issue Feb 14, 2018 · 40 comments
Labels
Bug Resolution: Locked This issue was locked by the bot.

Comments

@jgfidelis
Copy link

jgfidelis commented Feb 14, 2018

Is this a bug report?

Yes

Have you read the Contributing Guidelines?

Yes.

Environment

Environment:
OS: macOS Sierra 10.12.6
Node: 9.4.0
Yarn: 1.3.2
npm: 5.6.0
Watchman: 4.9.0
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
react: 16.2.0 => 16.2.0
react-native: 0.53.0 => 0.53.0

Edit: according to @MateRyze, it still happens on react-native 0.55.4.

Target Platform: Android 6.0.1

Steps to Reproduce

We have a Camera component and it should check for the Camera permission before mounting.

In my app's AndroidManifest.xml I have the line, along with many other permissions:

<uses-permission android:name="android.permission.CAMERA"/>

In our component's componentDidMount() we call a function that should return true if we have permission and false if we do not have, here is the relevant snippet of the function:

if (Platform.OS === 'android') {
const isGranted = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.CAMERA);
      if (isGranted) {
        return true;
      }
      try {
        console.log('before request');
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.CAMERA,
          {
            title: 'Dialog Title',
            message: 'Dialog Message',
          }
        );
        console.log('after request');
        return granted === PermissionsAndroid.RESULTS.GRANTED;
      } catch (err) {
        console.log('error');
        console.log(err);
      }
}

Expected Behavior

A dialog with my title and message should appear, if the user clicks on "Allow", the promise should resolve and my component should render as expected.

Actual Behavior

A dialog with a different message and title appears. I click on "Allow" and the promise is never resolved or rejected.

In my logs, only the "before request" log appears. Neitherconsole.log('after request') or console.log('error') is logged, so I presume the code is stuck in the await.

I am following this doc.

@jgfidelis
Copy link
Author

up :(

@hramos hramos added the Android label Mar 5, 2018
@react-native-bot react-native-bot added the Platform: macOS Building on macOS. label Mar 20, 2018
@hramos hramos removed the Platform: macOS Building on macOS. label Mar 29, 2018
@aryo
Copy link

aryo commented Apr 18, 2018

Yup encountering the same behavior... seems like it will only resolve if the device is < Android 6.0

@jgfidelis
Copy link
Author

Up again. This error happens in one of our apps in production, we tried to make a workaround for it multiple times but nothing works. Even if we ask for the permission when the app starts, it still hangs and never resolves.

@aryo, will try to confirm what you said, thanks

Would love any follow up

@SchmidmajerReka
Copy link

The alert asking for permission is shown as expected, but sometimes in case of denial the promise do not resolves and because of this the app flow stops. If the permission is granted the flow goes as expected, the promise resolves.

@jslz
Copy link

jslz commented May 10, 2018

This is happening to us, appears to most reliably happen on one of our testers' Nexus 6; doesn't repro on some other Android devices. For us no matter if the permission is granted or denied, it can lead to the unresolving promise it seems.
react-native-cli: 2.0.1
react-native: 0.51.0
platform: android
builds: at least release builds

@SchmidmajerReka
Copy link

It happens with different android versions and different devices for us.
First we hoped it would be because of the old react native version 0.38 it is, but i don't think this is the case after your comment jslz.
We tried different build tool versions and target/compile versions. The issue still remains the same.

@react-native-bot
Copy link
Collaborator

Thanks for posting this! It looks like your issue may refer to an older version of React Native. Can you reproduce the issue on the latest release, v0.55?

Thank you for your contributions.

@jslz
Copy link

jslz commented May 15, 2018

We are trying to upgrade to 0.54, we generally avoid being on the bleeding edge of RN for stability reasons. It would be helpful to know if there's been an explicit fix ever done for this issue. :-)

@MateRyze
Copy link

MateRyze commented May 17, 2018

I have a similar problem with PERMISSIONS.ACCESS_FINE_LOCATION: the dialog doesn't appear and the promise is also not resolved.
I am using code from docs.
react-native version: 0.55.4

@jslz
Copy link

jslz commented May 17, 2018

@MateRyze as an aside & by the by, apparently some Android permissions are not considered "dangerous" and so I guess those ones do not put up an extra dialog box from Android OS itself?

https://stackoverflow.com/questions/34808769/android-6-0-what-is-the-difference-between-dangerous-and-special-permissions

(That's separate from the promise-never-resolving issue.)

@rcidt
Copy link

rcidt commented May 24, 2018

@jgfidelis Are you using react-native-navigation?

I have the same issue you have, and I think it is because the onRequestPermissionsResult method in the MainActivity never get's called due to NavigationActivity.

@jslz
Copy link

jslz commented May 24, 2018

@rcidt, yes fwiw we are using wix rnn.

@rcidt
Copy link

rcidt commented May 24, 2018

@jslz I am 99% sure that is the reason the promise never resolves. I am opening a ticket with them, maybe they can help.

@MateRyze
Copy link

@jslz but the location permission is dangerous. Moreover it doesn't resolve :(

@jslz
Copy link

jslz commented May 24, 2018

@MateRyze oh dang. Thanks for pointing that out.

@SchmidmajerReka
Copy link

SchmidmajerReka commented May 24, 2018 via email

@jgfidelis
Copy link
Author

@rcidt No, we do not use react-native-navigation on the app we have this issue.

@rcorrie
Copy link

rcorrie commented May 25, 2018

I am seeing this happen 90% of the time. A few times the promise actually resolves, but that's like 10% of the time.

This issue is making our android app basically unusable :(

@rcorrie
Copy link

rcorrie commented May 29, 2018

Updated to RN 0.55 and I have no more issues with PermissionsAndroid

@meylor
Copy link

meylor commented Jun 11, 2018

Confirmed, upgrading to the following versions fixes the issue:

    "react": "16.4.0",
    "react-native": "0.55.4",

@MateRyze
Copy link

Using following versions:
"react": "16.4.0",
"react-native": "0.55.4",
No other modules installed.

Problem: no dialog and the request doesn't resolve. :(
I am using the code from https://facebook.github.io/react-native/docs/permissionsandroid.htm

async function requestLocationPermission() {
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      {
        'title': 'Cool Photo App Camera Permission',
        'message': 'Cool Photo App needs access to your camera ' +
          'so you can take awesome pictures.'
      }
    )
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      console.log("You can use the location service")
    } else {
      console.log("Location permission denied")
    }
  } catch (err) {
    console.warn(err)
  }
}

@meylor
Copy link

meylor commented Jun 11, 2018

@MateRyze before you installed:

"react": "16.4.0",
"react-native": "0.55.4",

did you also do a rm -rf ./node_modules package-lock.json?

The only difference might be that I'm using the "promise/then" syntax in lieu of "async/await", ex:

    requestAndroidPermissions() {
        if (Platform.OS === 'android') {
            var permissions = [
                PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION
            ];

            try {
                PermissionsAndroid.requestMultiple(permissions).then(granted => {
                    // Object.entries(granted).map(([key, value]) => {
                    // });
                    this.nextAction();
                });
            } catch (err) {
                console.warn(err);
            }
        } else if (Platform.OS === 'ios') {
            this.nextAction();
        }
    }

which shouldn't matter, but perhaps it does.

@meylor
Copy link

meylor commented Jun 11, 2018

@MateRyze also using

PermissionsAndroid.requestMultiple()

@jgfidelis
Copy link
Author

@MateRyze this is a long shot, but can you try changing your code to use then rather then awai/async just to see if the bug still happens? I don't think it will make any difference, but lets try anything...

@jgfidelis
Copy link
Author

We fixed it by requesting the permission on app startup.

@alvarolorentedev
Copy link

After debugging and trying a few cases. If the request is called with the rationale parameter as undefined the request permission works correctly.
When the rationale object is provided permissions are not requested.

@asleepace
Copy link

I just wrapped it in another promise, seems to work well for me.

getPermissions() {
  return new Promise(async(resolve, reject) => {
    const permissions = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
    if (permissions === PermissionsAndroid.RESULTS.GRANTED) resolve(true);
    else reject(false);
  });
}

@alvarolorentedev
Copy link

alvarolorentedev commented Aug 22, 2018

@asleepace so PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE) works because the rationale is undefined at least in the version that was on react-native-camera (react-native version: ^0.55.2).
What happens if you pass rationale as the second parameters?

@asleepace
Copy link

asleepace commented Aug 22, 2018

@kanekotic still works with the rationale for me as well, using RN version 0.55.4

@thamarai199
Copy link

still the issue persists. I'm using RN v0.53. Any workaround, as I don't want to upgrade my RN version

@talaikis
Copy link

Here's perfectly working example for fresh 0.57 and Android 27 on physical phone:

class App extends Component {
  _requestPermissions = async () => {
    if (Platform.OS === 'android') { 
      const result = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA)
      return result === PermissionsAndroid.RESULTS.GRANTED || result === true
    }
    return true
  }

  componentDidMount = () => {
    async ({ _, status }) => {
      if (status !== 'PERMISSION_GRANTED') {
        await this._requestPermissions()
      }
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <RNCamera style={styles.preview} type={RNCamera.Constants.Type.back} />
      </View>
    )
  }
}

So, basically an error is rather how and what permissions to ask, not React Native related. For example, if we would have used if (status !== 'PENDING_AUTHORIZATION') {, then the app will pop-up only on second run and first run will be promise rejected.

@sfuqua
Copy link

sfuqua commented Jan 4, 2019

In our case this was happening because our main activity does not extend ReactActivity and we were not properly implementing PermissionAwareActivity on our own.

The symptom we were seeing - permission prompt would show up properly, user could allow/deny, and then... nothing. If the user allowed the permission, subsequent attempts would succeed (promise would resolve), but the first allow never resolved and denies never resolved.

ReactActivity has some glue that handles notifying React Native that a permissions request is finished via PermissionListener. We had to roll this ourselves - when React calls requestPermissions on the activity, save off the provided PermissionListener, and then later call listener.onRequestPermissionsResult when your activity's onRequestPermissionsResult is invoked.

@Hamzehn
Copy link

Hamzehn commented Feb 5, 2019

I am running into this problem with PermissionsAndroid.requestMultiple() when permissions are not already granted. If permissions are not already granted when requestMultiple() is called and the dialog has to be shown to the user, the promise never gets fulfilled.

@hramos hramos removed the Bug Report label Feb 6, 2019
@moahmed123
Copy link

moahmed123 commented Feb 17, 2019

_requestLocationPermission(){ return new Promise(async() => { const permissions = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION); if (permissions === PermissionsAndroid.RESULTS.GRANTED){ alert('access true'); } else{ alert('access false'); } }); }

@mateuspiresl
Copy link

Happening on RN 0.58.3.

@ferrannp
Copy link
Contributor

Hello there 👋 this issue has been reported for an old version of React Native. Ideally we'd like everyone to be using 0.59 (see the awesome changes it brought) but we know updating can be a pain. We are going to close this issue because it's from a version before 0.57, which is really old.

But please, if it's actually still an issue with 0.59 please comment below and we can reopen it 😊

@777uday
Copy link

777uday commented Jun 13, 2019

Any way to provide rationale to .multipleRequest()?. I want to give the user more insight into why I need the permission for respective request. In short, Customized title and message with multiple requests.

@luisaverza
Copy link

luisaverza commented Sep 25, 2019

I'm using:

"react": "16.8.3",
"react-native": "0.59.9",

Relevant snippet:

  const askCameraPermission = async () => {
    try {
      const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA);
      console.log(granted)
    } catch {
      (e) => console.log(e)
    };
  };

App info's permissions after -> before running method

pending -> granted BUT promise is not resolved, console.log doesn't show. 👎
granted -> don't ask for permission because is already granted AND promise is resolved, console.log show 'granted' 👍

@NayakShreyas
Copy link

NayakShreyas commented Dec 13, 2019

I have upgraded my project from 0.57 to 0.61 . But the issue still exists. However if I try to create a new project with react-native 0.61 this issue is not there. I am stuck here. Please some one help me

@BoatingZeng
Copy link

I have upgraded my project from 0.57 to 0.61 . But the issue still exists. However if I try to create a new project with react-native 0.61 this issue is not there. I am stuck here. Please some one help me

Maybe you Override onRequestPermissionsResult in MainActivity extends ReactActivity but forget to call super.onRequestPermissionsResult.

@facebook facebook locked as resolved and limited conversation to collaborators Mar 19, 2020
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Mar 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests