Expo Contacts getContactsAsync() not working on device

Hello, i’m working on an app that allows users to add people to a team via phone contacts, and I am using the Expo Contacts module (import * as Contacts from “expo-contacts”; )

This works with no problem on my android emulator, however when I run the app through the expo client app (via the QR code or published app) I get a series of errors from the following function:

openContactsAsync = async () => {
    const { status } = await Contacts.requestPermissionsAsync();
    if (status === "granted") {
      const { data } = await Contacts.getContactsAsync();

      if (data.length > 0) {
        const contact = data[0];
        console.log(contact);
        this.setState({ contactData: data });
      }
    }
  };

the data object and everything belonging to it is undefined, meaning I cant create the following modal when the user clicks “add user via contact”:

modalPopUp = () => {
    return (
      <Modal visible={this.state.showPopUp}>
        <View style={CStyles.modalBackground}>
          <View style={CStyles.modalForeground}>
            <View style={CStyles.modalScrollContainer}>
              <ScrollView
                style={{}}
                contentContainerStyle={{
                  justifyContent: "center",
                  alignContent: "center",
                  alignItems: "center",
                }}
              >
                {this.state.contactData.map((contact) => {
                  // alert(this.state.contactData[0].name);

                  if (contact.phoneNumbers.length > 0) {
                    return (
                      <TouchableOpacity
                        style={CStyles.listItemCard}
                        key={contact.id}
                        onPress={() => {
                          this.setState({
                            selectedImage: contact.image,
                          });
                          this.setState({ name: contact.name });
                          this.setState({
                            phone: contact.phoneNumbers[0].number,
                          });
                          this.setState({ showPopUp: false });
                        }}
                      >
                        <View style={CStyles.listItemContainer}>
                          <View
                            style={{
                              flex: 3,
                              alignItems: "center",
                              justifyContent: "center",
                            }}
                          >
                            <Image
                              style={{
                                width: 56,
                                height: 56,
                                margin: 8,
                              }}
                              source={
                                contact.imageAvailable
                                  ? { uri: contact.image } // Use object with 'uri'
                                  : require("../../assets/LogoImage.png") // Or use require call directly
                              }
                            />
                          </View>
                          <View
                            style={{
                              flex: 6,
                              alignItems: "flex-start",
                              justifyContent: "center",
                            }}
                          >
                            <Text style={{ fontSize: 16 }}>{contact.name}</Text>
                            <Text style={{ fontSize: 12 }}>
                              Number: {contact.phoneNumbers[0].number}
                            </Text>
                          </View>
                        </View>
                      </TouchableOpacity>
                    );
                  }
                })}
              </ScrollView>
            </View>
            <Text
              style={[CStyles.buttonText, { color: "black" }]}
              onPress={() => {
                this.setState({ showPopUp: false });
              }}
            >
              Close
            </Text>
          </View>
        </View>
      </Modal>

any help would be appreciated!

package.json:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "nodemon-server": "nodemon-server.bat",
    "chrome": "set BROWSER=%ProgramFiles(x86)%\\Google\\Chrome\\Application\\chrome.exe && expo start --android",
    "concur": "npm-run-all --parallel chrome nodemon-server"
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.11.0",
    "@react-native-community/masked-view": "0.1.10",
    "@react-navigation/bottom-tabs": "^5.8.0",
    "@react-navigation/drawer": "^5.9.0",
    "@react-navigation/material-top-tabs": "^5.2.16",
    "@react-navigation/native": "^5.7.3",
    "@react-navigation/stack": "^5.9.0",
    "expo": "~38.0.8",
    "expo-contacts": "~8.2.1",
    "expo-image-picker": "~8.3.0",
    "expo-status-bar": "^1.0.2",
    "nodemon": "^2.0.4",
    "npm-run-all": "^4.1.5",
    "react": "~16.11.0",
    "react-dom": "~16.11.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
    "react-native-contacts": "^5.2.5",
    "react-native-gesture-handler": "~1.6.0",
    "react-native-keyboard-aware-scrollview": "^2.1.0",
    "react-native-reanimated": "~1.9.0",
    "react-native-safe-area-context": "~3.0.7",
    "react-native-screens": "~2.9.0",
    "react-native-web": "~0.11.7",
    "react-navigation": "^4.4.0",
    "react-navigation-drawer": "^2.5.0",
    "react-navigation-stack": "^2.8.2",
    "react-navigation-tabs": "^2.9.0"
  },
  "devDependencies": {
    "@babel/core": "^7.8.6",
    "babel-preset-expo": "~8.1.0"
  },
  "private": true
}

Solved! Some contacts don’t have phoneNumbers as a property so adding a check in the modal before checking for phoneNumbers.length fixed the problem

Happy to hear you got things sorted out, @frankiejlyons.

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.