react-native-contacts: Contacts.getAll() crashes Android app when permissions are not granted
Expected Behaviour:
If permissions are not granted, the callback should be called, with the error
field being non-null/undefined.
Contacts.getAll((err, contacts) => {
// err should be defined
})
Actual Behaviour:
App crashes completely. React Native does not even have the chance to catch the error.
My code:
async function requestPermissions() {
let status = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_CONTACTS)
console.log('status', status)
}
async function contactsGetAll(): Promise<Contact[]> {
await requestPermissions()
console.log('permissions')
return new Promise((res, rej) => {
Contacts.getAll((err, contacts) => {
console.log('err', err)
if (err) { rej(err) }
else { res(contacts) }
})
})
}
contacts: Contact[] = await contactsGetAll()
console.log output:
status: never_ask_again
permissions
// crashes
Workaround fix:
Check permissions before calling Contacts.getAll()
let status = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_CONTACTS)
if (status === 'denied' || status === 'never_ask_again') {
throw Error('Permissions not granted to access Contacts')
}
Contacts.getAll((err, contacts) => {})
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 5
- Comments: 15 (2 by maintainers)
I’m not sure if there’s anything we can/should do about this. Checking for permissions before performing privileged actions seems fine to me.
in android manifest file use
i do not understand why i need READ_PROFILE ?
Btw, just sharing my code if anyone just wants a quick copy and paste:
Usage:
Contacts.ts
There is inconsistent behaviour on Android vs iOS though.
In iOS, permissions aren’t granted, it will be handled in the error block:
In Android, if permissions are not granted, errors do not get caught by this block. It crashes the entire app entirely.
Why provide an error handler for when the error handler only catches iOS errors and not Android errors? It’s misleading to developers to see an error handler block that does not catch errors. I feel it would be better if both Android & iOS were handled the same way.
It does not seem appropriate that calling a ReactNative function can cause an entire Android app to crash. I feel errors should be handled at the ReactNative boundary.
I solved it by the using the below piece of “try catch” code logic:
The app will not crash, since all the cases are handled .
Hope this helps 👍
i’m on version 7.0.7 and adding
<uses-permission android:name="android.permission.READ_CONTACTS" />
fixed my issue on react-native 0.70.6The newer way of calling Contacts.getAll() is now as follows: