Hello friends, It’s been few days since I am trying to run the React Native Contacts NPM package in my react native project. But It showing me same error again and again and not run properly. So I start reading their GitHub documentation and found out that the latest version of package does not work properly with latest version of react native. But the version 5.2.3 is Stable and works properly in both Android and iOS devices. So we’re using the older version in our tutorial. Now what we are doing in our tutorial is, We would access the android and iOS device contacts and show them into FlatList component. User can also Edit and Delete contacts. So in this tutorial we would learn about Example of React Native Contacts – Show Device Contacts in RN.
Contact in this project Example of React Native Contacts – Show Device Contacts in RN :-
1. First of all we have to install the React Native Contacts NPM package in our project. So open your RN project in Command Prompt in Windows and Terminal in MAC and execute below command.
1
|
npm install react–native–contacts@5.2.3 —save
|
Screenshot After done installation :-
Now the package is successfully installed in our project. Next step is to start configuring it in both Android and iOS. Read all the below steps carefully.
2. Configure React Native Contacts in Android :-
1. In android we have to perform only 1 Step to setup the contacts package. Go to Your-React-Native-Project -> android -> app -> src -> main -> AndroidManifest.xml file. Now add both permission.
1
2
|
<uses–permission android:name=“android.permission.WRITE_CONTACTS”/>
<uses–permission android:name=“android.permission.READ_CONTACTS”/>
|
Source Code of my AndroidManifest.xml file :-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
package=“com.myapp”>
<uses–permission android:name=“android.permission.INTERNET” />
<uses–permission android:name=“android.permission.WRITE_CONTACTS”/>
<uses–permission android:name=“android.permission.READ_CONTACTS”/>
<application
android:name=“.MainApplication”
android:label=“@string/app_name”
android:icon=“@mipmap/ic_launcher”
android:roundIcon=“@mipmap/ic_launcher_round”
android:allowBackup=“false”
android:theme=“@style/AppTheme”>
<activity
android:name=“.MainActivity”
android:label=“@string/app_name”
android:configChanges=“keyboard|keyboardHidden|orientation|screenSize|uiMode”
android:launchMode=“singleTask”
android:windowSoftInputMode=“adjustResize”>
<intent–filter>
<action android:name=“android.intent.action.MAIN” />
<category android:name=“android.intent.category.LAUNCHER” />
</intent–filter>
</activity>
</application>
</manifest>
|
2. Now we have to clear the App gradle and built it again.
1
|
cd android && gradlew clean && cd..
|
3. Configure React Native Contacts in iOS :-
1. Go to Your-React-Native-Project -> iOS -> appName.xcodeproj file in XCode.
2. Select Your-App-Name -> Info .
3. Click on the Plus + Button .
4. Select Privacy – Contact Usages Description Permission from List and add it.
5. Now we have to install the PODS to link the package. Execute the below command.
1
|
cd ios && pod install && cd ..
|
Here you go. Now your react native iOS project is ready to use.
4. Start Coding for App :-
1. Open your project’s main App.js file and import useState, useEffect, FlatList, StyleSheet, PermissionsAndroid, Text, View, Platform, Alert, TouchableOpacity and PropTypes component.
1
2
3
4
5
|
import React, { useState, useEffect } from ‘react’;
import { FlatList, StyleSheet, PermissionsAndroid, Text, View, Platform, Alert, TouchableOpacity } from ‘react-native’;
import PropTypes from ‘prop-types’;
|
2. Import Contacts component from ‘react-native-contacts’ package.
1
|
import Contacts from ‘react-native-contacts’;
|
3. Creating a Constant stand alone component named as CustomItem with Props. We would use this component to render Items from Contact List into our main FlatList.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
const CustomItem = (props) => {
const shouldComponentUpdate = () => {
return false;
};
const { item, onPress } = props;
return (
<View>
<TouchableOpacity onPress={() => onPress(item)}>
<View style={styles.row}>
<View style={styles.avatarContainer}>
</View>
<View style={styles.listTextContainer}>
<View style={{ justifyContent: ‘center’ }}>
<Text style={{ fontSize: 18 }}> {`${item.givenName} ${item.familyName}`} </Text>
</View>
</View>
</View>
</TouchableOpacity>
</View>
);
};
|
4. Creating our main Export default App component.
1
2
3
4
5
|
export default function App() {
}
|
5. Creating a State named as contacts with State update method setContacts. We would use this State to store accessed contacts.
1
|
let [contacts, setContacts] = useState([]);
|
6. Creating useEffect() method, Now in the method we would First Ask for Permission for Android and iOS devices then call the accessContacts() function to fetch contacts from device.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
useEffect(() => {
if (Platform.OS === ‘android’) {
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CONTACTS, {
title: ‘Access Contacts’,
message: ‘App Want to View your Phone Contacts.’,
}).then(() => {
accessContacts();
}
);
} else {
accessContacts();
}
}, []);
|
7. Creating the accessContacts() method. In this function we would Access the device contacts and store them into contacts State.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
const accessContacts = () => {
Contacts.getAll((err, data) => {
data.sort(
(a, b) =>
a.givenName.toLowerCase() > b.givenName.toLowerCase(),
);
if (err === ‘denied’) {
Alert.alert(‘Permission to access contacts was denied’);
console.warn(‘Permission to access contacts was denied’);
} else {
setContacts(data);
}
});
};
|
8. Creating a function openContact(). In this function we would simply open the Selected contact into Edit view.
1
2
3
|
const openContact = (contact) => {
Contacts.openExistingContact(contact, () => { });
};
|
9. Creating a function itemSeparator(). We would use this function to render horizontal divider line between each item in Flat List.
1
2
3
4
5
6
7
8
9
10
11
|
const itemSeparator = () => {
return (
<View
style={{
height: 1,
width: “100%”,
backgroundColor: “#607D8B”,
}}
/>
);
}
|
10. Creating return() block, Here we would make our main FlatList component.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
return (
<View style={styles.MainContainer}>
<Text style={styles.title}>
Show Contact List in React Native
</Text>
<FlatList
data={contacts}
renderItem={(contact) => {
return (
<CustomItem
key={contact.item.recordID}
item={contact.item}
onPress={openContact}
/>
);
}}
keyExtractor={(item) => item.recordID}
ItemSeparatorComponent={itemSeparator}
/>
</View>
);
|
11. Now we have to declare the default Prop types for our CustomItem component.
1
2
3
4
|
CustomItem.propTypes = {
item: PropTypes.object,
onPress: PropTypes.func,
};
|
12. Creating Style.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
const styles = StyleSheet.create({
MainContainer: {
flex: 1,
paddingTop: (Platform.OS === ‘ios’) ? 20 : 0,
},
title: {
padding: 12,
fontSize: 22,
backgroundColor: ‘#33691E’,
color: ‘white’,
},
contactTitle: {
fontSize: 22,
paddingTop: 8,
paddingBottom: 8,
paddingLeft: 15,
color: ‘black’
},
row: {
flexDirection: ‘row’,
height: 60,
},
avatarContainer: {
marginLeft: 12,
justifyContent: ‘center’,
alignItems: ‘center’,
},
listTextContainer: {
marginLeft: 15,
flexDirection: ‘row’,
flex: 1,
}
});
|
13. Complete Source Code for App.js file :-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
import React, { useState, useEffect } from ‘react’;
import { FlatList, StyleSheet, PermissionsAndroid, Text, View, Platform, Alert, TouchableOpacity } from ‘react-native’;
import PropTypes from ‘prop-types’;
import Contacts from ‘react-native-contacts’;
const CustomItem = (props) => {
const shouldComponentUpdate = () => {
return false;
};
const { item, onPress } = props;
return (
<View>
<TouchableOpacity onPress={() => onPress(item)}>
<View style={styles.row}>
<View style={styles.avatarContainer}>
</View>
<View style={styles.listTextContainer}>
<View style={{ justifyContent: ‘center’ }}>
<Text style={{ fontSize: 18 }}> {`${item.givenName} ${item.familyName}`} </Text>
</View>
</View>
</View>
</TouchableOpacity>
</View>
);
};
export default function App() {
let [contacts, setContacts] = useState([]);
useEffect(() => {
if (Platform.OS === ‘android’) {
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CONTACTS, {
title: ‘Access Contacts’,
message: ‘App Want to View your Phone Contacts.’,
}).then(() => {
accessContacts();
}
);
} else {
accessContacts();
}
}, []);
const accessContacts = () => {
Contacts.getAll((err, data) => {
data.sort(
(a, b) =>
a.givenName.toLowerCase() > b.givenName.toLowerCase(),
);
if (err === ‘denied’) {
Alert.alert(‘Permission to access contacts was denied’);
console.warn(‘Permission to access contacts was denied’);
} else {
setContacts(data);
}
});
};
const openContact = (contact) => {
Contacts.openExistingContact(contact, () => { });
};
const itemSeparator = () => {
return (
<View
style={{
height: 1,
width: “100%”,
backgroundColor: “#607D8B”,
}}
/>
);
}
return (
<View style={styles.MainContainer}>
<Text style={styles.title}>
Show Contact List in React Native
</Text>
<FlatList
data={contacts}
renderItem={(contact) => {
return (
<CustomItem
key={contact.item.recordID}
item={contact.item}
onPress={openContact}
/>
);
}}
keyExtractor={(item) => item.recordID}
ItemSeparatorComponent={itemSeparator}
/>
</View>
);
};
CustomItem.propTypes = {
item: PropTypes.object,
onPress: PropTypes.func,
};
const styles = StyleSheet.create({
MainContainer: {
flex: 1,
paddingTop: (Platform.OS === ‘ios’) ? 20 : 0,
},
title: {
padding: 12,
fontSize: 22,
backgroundColor: ‘#33691E’,
color: ‘white’,
},
contactTitle: {
fontSize: 22,
paddingTop: 8,
paddingBottom: 8,
paddingLeft: 15,
color: ‘black’
},
row: {
flexDirection: ‘row’,
height: 60,
},
avatarContainer: {
marginLeft: 12,
justifyContent: ‘center’,
alignItems: ‘center’,
},
listTextContainer: {
marginLeft: 15,
flexDirection: ‘row’,
flex: 1,
}
});
|
Screenshot in iOS :-