Can't import Contacts from 'react-native-contacts' - react-native

I have already tried to solve this problem using
react-native-contacts getAll return null,
react-native-contacts returns undefined.
But, unfortunately, I can't get success.
I've already run below shells:
npm install react-native-contacts --save
react-native link react-native-contacts
Here is my code =========
import Contacts from 'react-native-contacts';
componentDidMount() {
if(Platform.OS === 'ios'){
Contacts.getAll((err, contacts) => {
if (err) {
throw err;
}
// contacts returned
console.log("contacts => ", contacts);
})
}else if(Platform.OS === 'android'){
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
{
title: 'Contacts',
message: 'This app would like to view your contacts.'
}
).then(() => {
Contacts.getAll((err, contacts) => {
if (err === 'denied'){
// error
} else {
// contacts returned in Array
console.log("contacts => ", contacts);
}
})
})
}
}
======================================
Here is my result.
screen shoot my error terminal
My environment :
> expo --version
> 4.0.6
> node --version
> v14.15.0
> npm --version
> 6.14.8

As You Are Using Expo You Can Try Using The Contacts Module From Expo . The Documentation For Contacts https://docs.expo.io/versions/v32.0.0/sdk/contacts/ .
In Case You Want To Use react-native-contacts You must eject expo and continue with react-native-cli
import { Contacts } from 'expo';
const { data } = await Contacts.getContactsAsync({
fields: [Contacts.Fields.Emails],
});
if (data.length > 0) {
const contact = data[0];
console.log(contact);
}

Related

TVEventHandler Module is not installed

I am trying to build an application for android tv. But when use 'TVEventHandler' It show TVEventHandler Module is not installed. I also try to install TVEventHandler but it show:
Standard error:
E404
Not Found - GET https://registry.npmjs.org/TVEventHandler - Not found
Here Is my Code:
_tvEventHandler: any;
_enableTVEventHandler() {
this._tvEventHandler = new TVEventHandler();
this._tvEventHandler.enable(this, function (cmp, evt) {
if (evt && evt.eventType === 'right') {
cmp.setState({ board: cmp.state.board.move(2) });
} else if (evt && evt.eventType === 'up') {
cmp.setState({ board: cmp.state.board.move(1) });
} else if (evt && evt.eventType === 'left') {
cmp.setState({ board: cmp.state.board.move(0) });
} else if (evt && evt.eventType === 'down') {
cmp.setState({ board: cmp.state.board.move(3) });
} else if (evt && evt.eventType === 'playPause') {
cmp.restartGame();
}
});
}
_disableTVEventHandler() {
if (this._tvEventHandler) {
this._tvEventHandler.disable();
delete this._tvEventHandler;
}
}
componentDidMount() {
this._enableTVEventHandler();
}
componentWillUnmount() {
this._disableTVEventHandler();
}
It's because TVEventHandler and other components for build android tv deleted from react native core.
So you should run this command and it's converted your react native to tv os:
yarn add react-native#npm:react-native-tvos#latest
And your react native version after install react-native-tvos :
Now TVEventHandler and another tv build components added to your react native if you checked ./node_modules/react_native/Libraries/components

On running my Code on Android Device I get an error as: Execution failed for task ':rn-fetch-blob:compileDebugJavaWithJavac'

I am using the rn-fetch-blob package to download files from url. But on running the code, on android it throws an error as: Execution failed for task ':rn-fetch-blob:compileDebugJavaWithJavac'.
In terminal: Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
This is my code:
import React, { Component } from "react";
import {
View,
Text,
Button,
Alert,
ProgressBarAndroid,
ToastAndroid,
PermissionsAndroid
} from "react-native";
import RNFetchBlob from "rn-fetch-blob";
export default class componentName extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
loading: false
};
}
actualDownload = () => {
this.setState({
progress: 0,
loading: true
});
let dirs = RNFetchBlob.fs.dirs;
RNFetchBlob.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
path: dirs.DownloadDir + "/path-to-file.png",
fileCache: true
})
.fetch(
"GET",
"http://www.usa-essays.com/blog/wp-content/uploads/2017/09/sample-5-1024x768.jpg",
{
//some headers ..
}
)
.progress((received, total) => {
console.log("progress", received / total);
this.setState({ progress: received / total });
})
.then(res => {
this.setState({
progress: 100,
loading: false
});
ToastAndroid.showWithGravity(
"Your file has been downloaded to downloads folder!",
ToastAndroid.SHORT,
ToastAndroid.BOTTOM
);
});
};
async downloadFile() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: "Storage Permission",
message: "App needs access to memory to download the file "
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.actualDownload();
} else {
Alert.alert(
"Permission Denied!",
"You need to give storage permission to download the file"
);
}
} catch (err) {
console.warn(err);
}
}
render() {
return (
<View>
<Text> Download Files in Android </Text>
<Button onPress={() => this.downloadFile()} title="Download" />
{this.state.loading ? (
<ProgressBarAndroid
styleAttr="Large"
indeterminate={false}
progress={this.state.progress}
/>
) : null}
</View>
);
}
}
React native 0.60 brings some breaking changes both to Android and iOS.
For the android part the solution (workaround) is explained here: https://facebook.github.io/react-native/blog/2019/07/03/version-60#androidx-support
1) npm install --save-dev jetifier
2) npx jetify
3) npx react-native run-android
4) npx jetify
You will have to do step 4 everytime you add a new module or reset your node_modules folder.
Let me know if this solved your issue
Using React Native version 0.59.0 and 0.60.0 was breaking through and giving errors linked to libraries.
Workout: React Native 0.59.9 Just worked fine.
For the RN 0.60.0, they are giving support for the AndroidX,
You can use the following command to fix this issue.
npm i jetifier
npx jetify
You can refer the following doc for the AndroidX Support.
Ref: https://facebook.github.io/react-native/blog/2019/07/03/version-60
Please go to react-native-fetch-blob/android/build.gradle and update these values
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
to these
compileSdkVersion 26
buildToolsVersion "26.0.3"
defaultConfig {
minSdkVersion 16
targetSdkVersion 26
versionCode 1
versionName "1.0"
}

How do I request multiple permissions at once in react native

I'd like to request permissions on one page instead of waiting for each particular situation. However, I do not want multiple popups. Is there a way to ask for permissions with a single popup/modal.
On the android side I found this post and this, which look promising, but I have yet to find something for iOS.
In Android
First add permissions in to the AndroidManifest.xml file and then
if (Platform.OS === 'android') {
PermissionsAndroid.requestMultiple(
[PermissionsAndroid.PERMISSIONS.CAMERA,
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE]
).then((result) => {
if (result['android.permission.ACCESS_COARSE_LOCATION']
&& result['android.permission.CAMERA']
&& result['android.permission.READ_CONTACTS']
&& result['android.permission.ACCESS_FINE_LOCATION']
&& result['android.permission.READ_EXTERNAL_STORAGE']
&& result['android.permission.WRITE_EXTERNAL_STORAGE'] === 'granted') {
this.setState({
permissionsGranted: true
});
} else if (result['android.permission.ACCESS_COARSE_LOCATION']
|| result['android.permission.CAMERA']
|| result['android.permission.READ_CONTACTS']
|| result['android.permission.ACCESS_FINE_LOCATION']
|| result['android.permission.READ_EXTERNAL_STORAGE']
|| result['android.permission.WRITE_EXTERNAL_STORAGE'] === 'never_ask_again') {
this.refs.toast.show('Please Go into Settings -> Applications -> APP_NAME -> Permissions and Allow permissions to continue');
}
});
}
In iOS
In the info section of your project on XCode
Add the permissions and the description
say - ex: Privacy - Contacts Usage Description
then,
Permissions.request('photo').then(response => {
if (response === 'authorized') {
iPhotoPermission = true;
}
Permissions.request('contact').then(response => {
if (response === 'authorized') {
iPhotoPermission = true;
}
});
});
Makes sure you also add respective permissions in manifest file as well.
export async function GetAllPermissions() {
try {
if (Platform.OS === "android") {
const userResponse = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
PermissionsAndroid.PERMISSIONS.CALL_PHONE
]);
return userResponse;
}
} catch (err) {
Warning(err);
}
return null;
}
To request multiple permissions I will suggest you to use npm module as its saves time and easy to setup and most important you don't have to worry about the platforms :)
Installation
npm install --save react-native-permissions
Usage
import Permissions from 'react-native-permissions'
// Check the status of multiple permissions
_checkCameraAndPhotos = () => {
Permissions.checkMultiple(['camera', 'photo']).then(response => {
//response is an object mapping type to permission
this.setState({
cameraPermission: response.camera,
photoPermission: response.photo,
})
})
}
Don't forget to add permissions to AndroidManifest.xml for android and Info.plist for iOS (Xcode >= 8).
First add your permissions to "android/app/src/main/AndroidManifest.xml" file. You can use npm module in order to achieve your goal.
npm install --save react-native-permissions
After installation, you can use checkMultiple function to ask multiple permissions. Following code illustrates how to ask permission for ANDROID.CAMERA and ANDROID.READ_EXTERNAL_STORAGE :
checkMultiple([
PERMISSIONS.ANDROID.CAMERA,
PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,
]).then(result => {
console.log(result);
});
The result will be an object like this
{"android.permission.CAMERA": "denied", "android.permission.READ_EXTERNAL_STORAGE": "denied"}
To handle this result, you can use this basic code example
checkPermissions = () => {
if (Platform.OS !== 'android') {
return;
}
checkMultiple([
PERMISSIONS.ANDROID.CAMERA,
PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,
]).then(result => {
if (
!result ||
!result[PERMISSIONS.ANDROID.CAMERA] ||
!result[PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE]
) {
console.log('could not get any result. Please try later.');
}
if (
result[PERMISSIONS.ANDROID.CAMERA] === RESULTS.GRANTED &&
result[PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE] === RESULTS.GRANTED
) {
console.log('granted for both permissions');
// do smthing here
}
});
};
There is also a way to request multiple permissions at once using react-native-permissions package.
you can also implement your own conditions according to need, i am just writing a simple solution
requestMultiple will not ask again if permissions are already granted.
import { checkMultiple, requestMultiple, PERMISSIONS } from 'react-native-permissions';
const verifyPermissions = async () => {
let perm = [ PERMISSIONS.IOS.CAMERA, PERMISSIONS.IOS.PHOTO_LIBRARY ];
if (Platform.OS == 'android') {
perm = [ PERMISSIONS.ANDROID.CAMERA, PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE ];
}
let permissionStatuses = await requestMultiple(perm);
console.log('obj', permissionStatuses);
console.log('Camera', permissionStatuses[perm[0]]);
console.log('photo', permissionStatuses[[ perm[1] ]]);
const result = permissionStatuses[perm[0]];
if (result !== 'granted') {
Alert.alert('Insufficient permissions!', 'You need to grant camera and library access permissions to use this app.', [
{ text: 'Okay' }
]);
return false;
}
return true;
};

'Attempt to invoke virtual method \'android.content.Context android.app.Application.getApplicationContext()\' on a null object reference'

I'm using https://github.com/AppsFlyerSDK/react-native-appsflyer in our react-native app.
I managed to set up the iOS part of it and ran the integration tests successfully
but I'm struggling with the Android integration.
1st problem:
When I build the app on my device I get this error:
'Attempt to invoke virtual method \'android.content.Context android.app.Application.getApplicationContext()\' on a null object reference'
inside the appsFlyer.initSdk
2nd problem:
When I run the Android SDK Integration test:
I get this result (see screenshot)
Here's my code :
```
...
...
// appsFlyer options
const options = {
devKey: 'Bl9i45ho07lp43',
isDebug: true,
};
if (Platform.OS === 'ios') {
options.appId = '1165972436';
}
this.onInstallConversionDataCanceller = appsFlyer.onInstallConversionData(
(data) => {
console.log(data);
}
);
appsFlyer.initSdk(options,
(result) => {
console.log(result);
},
(error) => {
console.error('error inside appsFlyer.initSdk ==>', error);
}
);
.....
.....
class App extends React.PureComponent {
state = {
appState: AppState.currentState,
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount() {
if (this.onInstallConversionDataCanceller) {
this.onInstallConversionDataCanceller();
}
AppState.removeEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
if (Platform.OS === 'ios') {
appsFlyer.trackAppLaunch();
}
}
if (this.state.appState.match(/active|foreground/) && nextAppState === 'background') {
if (this.onInstallConversionDataCanceller) {
this.onInstallConversionDataCanceller();
}
}
this.setState({ appState: nextAppState });
}
}
```
I found the solution:
Initially, I was following the documentation by adding
new RNAppsFlyerPackage(MainApplication.this) inside the getPackages() method in MainApplication.java but I kept having an error saying I couldn't use arguments with RNAppsFlyerPackage()
I had to remove the arguments so that I can build the project, but that didn't make the Android integration tests
1 - The solution was to clean the project
2 - delete the node_modules using :
rm -rf /node_modules
3- after doing that, I was prompted to use arguments inside the method
new RNAppsFlyerPackage(MainApplication.this)
and now the Android integration tests are passing

How can I download a file in react-native?

I ran this command in my console npm install react-native-fs --save
then have this code in my onclick function
_download = (downloadpath) => {
// console.log(introduction);
var RNFS = require('react-native-fs');
try {
RNFS.downloadFile({
fromUrl: downloadpath,
toFile: `${RNFS.DocumentDirectoryPath}/test.zip`,
}).promise.then((r) => {
this.setState({ isDone: true })
});
} catch (error) {
console.log(error);
// Error saving data
}
}
but its giving this
Well, unfortunately RNFS is not compatible with expo since it wraps native libraries. You can check it out usually in http://native.directory