Expo unable to retrieve contacts from Android

Hello,
I am trying to retrieve contacts from Andriod using Expo Contacts API.

But facing the below error

Can someone help look into this please

[11:28:15] [Unhandled promise rejection: TypeError: undefined is not an object (evaluating ‘_expo.default.Permissions’)]
*** screens/AddEventScreen.js:46:34 in componentDidMount$**
- node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch

import React from 'react';
import { Alert, StyleSheet, Text, View, ScrollView, Platform } from 'react-native';
import {
  Button,
  Container,
  Content,
  DatePicker,
  Form,
  Icon,
  Item,
  Input,
  Label,
  Picker,
  Textarea
} from 'native-base';
import AutoTags from 'react-native-tag-autocomplete';
import Expo from 'expo';


export default class AddEventScreen extends React.Component {
  static navigationOptions = {
    title: 'New Event',
  };

  constructor(props) {
    super(props);
    this.state = {
      chosenDate: new Date() ,
      selected: "00",
      fromHour: "00",
      fromMin: "00",
      toHour: "00",
      toMin: "00",
      contacts: [], // Will be populated during component mount
      suggestions : [{name:'Mickey Mouse'}, {'name': 'Bakthavatchalam'}],
      tagsSelected : [],
    };
    this.setDate = this.setDate.bind(this);
    this.handleDelete = this.handleDelete.bind(this);
    this.handleAddition = this.handleAddition.bind(this);
    this.componentDidMount = this.componentDidMount.bind(this);
  }

  async componentDidMount() {
    const time = Date.now();
    const permission = await Expo.Permissions.askAsync(Expo.Permissions.CONTACTS);
    if (permission.status !== 'granted') { return; }

    const contacts = await Expo.Contacts.getContactsAsync({
      fields: [
        Expo.Contacts.PHONE_NUMBERS,
        Expo.Contacts.EMAILS,
        Expo.Contacts.FIRST_NAME,
        Expo.Contacts.LAST_NAME
      ],
      pageSize: 10000,
      pageOffset: 0,
    }).then(({data, hasNextPage, hasPreviousPage, total}) => {
      var contactDetails = [];
      for (var i=0; i<data.length; i++){
        contactDetails.push({
          name: data[i].givenName + ' ' + data[i].familyName,
          phoneNumbers: data[i].phoneNumbers
        });
      }
      this.setState({contacts: contactDetails});
		});
  }

  handleDelete(index) {
   let tagsSelected = this.state.tagsSelected;
   tagsSelected.splice(index, 1);
   this.setState({ tagsSelected });
  }

  handleAddition(suggestion) {
    presentNames = [];
    for(var i =0;i<this.state.tagsSelected.length;i++){
      presentNames.push(this.state.tagsSelected[i].name);
    }
    if (presentNames.indexOf(suggestion.name) == -1){
      this.setState({ tagsSelected: this.state.tagsSelected.concat([suggestion])});
    }
  }

  setDate(newDate) {
    this.setState({ chosenDate: newDate });
  }

  onFromHourValueChange(value: string) {
    this.setState({
      fromHour: value
    });
  }

  onFromMinValueChange(value: string) {
    this.setState({
      fromMin: value
    });
  }

  onToHourValueChange(value: string) {
    this.setState({
      toHour: value
    });
  }

  onToMinValueChange(value: string) {
    this.setState({
      toMin: value
    });
  }

  handleChange(selectedOption: object) {
    this.setState({ selectedOption });
  }

  render(){
      return (
        <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
        <View style={{flex: 1, flexDirection: 'column'}}>
          <View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-end', alignContent: 'flex-end'}}>
            <Button iconLeft transparent primary>
              <Icon name='md-save'/>
            </Button>
            <Button iconLeft transparent primary>
              <Icon name='md-close'/>
            </Button>
          </View>
          <View style={{marginLeft: 15}}>
              <AutoTags
                suggestions={this.state.contacts}
                tagsSelected={this.state.tagsSelected}
                handleAddition={this.handleAddition}
                handleDelete={this.handleDelete}
                placeholder="Add a contact.." />
          </View>
          <Container>
          <Form>
            <Item floatingLabel>
              <Label>Subject</Label>
              <Input/>
            </Item>
            <Item floatingLabel>
              <Label>Description</Label>
              <Textarea rowSpan={5}/>
            </Item>
            <Item floatingLabel>
              <Label>Location</Label>
              <Input/>
            </Item>
            <Item>
              <Label>Date</Label>
              <DatePicker
                defaultDate={new Date(2018, 4, 4)}
                minimumDate={new Date(2018, 1, 1)}
                maximumDate={new Date(2018, 12, 31)}
                locale={"en"}
                timeZoneOffsetInMinutes={undefined}
                modalTransparent={false}
                animationType={"fade"}
                androidMode={"default"}
                placeHolderText="Select date"
                textStyle={{ color: "green" }}
                placeHolderTextStyle={{ color: "#d3d3d3" }}
                onDateChange={this.setDate}
                disabled={false}/>
            </Item>
            <Item>
              <Label>From</Label>
              <View style={{flex: 1, flexDirection: 'row'}}>
                <Picker
                  mode="dropdown"
                  placeholder="Hour"
                  iosIcon={<Icon name="arrow-down" />}
                  headerBackButtonText="Baaack!"
                  selectedValue={this.state.fromHour}
                  onValueChange={this.onFromHourValueChange.bind(this)}
                >
                  <Picker.Item label="00" value="00" />
                  <Picker.Item label="01" value="01" />
                  <Picker.Item label="02" value="02" />
                  <Picker.Item label="03" value="03" />
                  <Picker.Item label="04" value="04" />
                  <Picker.Item label="05" value="05" />
                  <Picker.Item label="06" value="06" />
                  <Picker.Item label="07" value="07" />
                  <Picker.Item label="08" value="08" />
                  <Picker.Item label="09" value="09" />
                  <Picker.Item label="10" value="10" />
                  <Picker.Item label="11" value="11" />
                  <Picker.Item label="12" value="12" />
                  <Picker.Item label="13" value="13" />
                  <Picker.Item label="14" value="14" />
                  <Picker.Item label="15" value="15" />
                  <Picker.Item label="16" value="16" />
                  <Picker.Item label="17" value="17" />
                  <Picker.Item label="18" value="18" />
                  <Picker.Item label="19" value="19" />
                  <Picker.Item label="20" value="20" />
                  <Picker.Item label="21" value="21" />
                  <Picker.Item label="22" value="22" />
                  <Picker.Item label="23" value="23" />
                </Picker>
                <Picker
                  mode="dropdown"
                  placeholder="Minutes"
                  iosIcon={<Icon name="arrow-down" />}
                  headerBackButtonText="Baaack!"
                  selectedValue={this.state.fromMin}
                  onValueChange={this.onFromMinValueChange.bind(this)}
                >
                  <Picker.Item label="00" value="00" />
                  <Picker.Item label="15" value="15" />
                  <Picker.Item label="30" value="30" />
                  <Picker.Item label="45" value="45" />
                </Picker>
              </View>
              </Item>
              <Item>
                <Label>To</Label>
                <View style={{flex: 1, flexDirection: 'row'}}>
                  <Picker
                    mode="dropdown"
                    placeholder="Hour"
                    iosIcon={<Icon name="arrow-down" />}
                    headerBackButtonText="Baaack!"
                    selectedValue={this.state.toHour}
                    onValueChange={this.onToHourValueChange.bind(this)}
                  >
                    <Picker.Item label="00" value="00" />
                    <Picker.Item label="01" value="01" />
                    <Picker.Item label="02" value="02" />
                    <Picker.Item label="03" value="03" />
                    <Picker.Item label="04" value="04" />
                    <Picker.Item label="05" value="05" />
                    <Picker.Item label="06" value="06" />
                    <Picker.Item label="07" value="07" />
                    <Picker.Item label="08" value="08" />
                    <Picker.Item label="09" value="09" />
                    <Picker.Item label="10" value="10" />
                    <Picker.Item label="11" value="11" />
                    <Picker.Item label="12" value="12" />
                    <Picker.Item label="13" value="13" />
                    <Picker.Item label="14" value="14" />
                    <Picker.Item label="15" value="15" />
                    <Picker.Item label="16" value="16" />
                    <Picker.Item label="17" value="17" />
                    <Picker.Item label="18" value="18" />
                    <Picker.Item label="19" value="19" />
                    <Picker.Item label="20" value="20" />
                    <Picker.Item label="21" value="21" />
                    <Picker.Item label="22" value="22" />
                    <Picker.Item label="23" value="23" />
                  </Picker>
                  <Picker
                    mode="dropdown"
                    placeholder="Minutes"
                    iosIcon={<Icon name="arrow-down" />}
                    headerBackButtonText="Baaack!"
                    selectedValue={this.state.toMin}
                    onValueChange={this.onToMinValueChange.bind(this)}
                  >
                    <Picker.Item label="00" value="00" />
                    <Picker.Item label="15" value="15" />
                    <Picker.Item label="30" value="30" />
                    <Picker.Item label="45" value="45" />
                  </Picker>
                </View>
                </Item>
          </Form>
          </Container>
          </View>
        </ScrollView>
      );
    }
}

const styles = StyleSheet.create({
  button: {
    height: 30,
    width: 100,
    justifyContent: 'center'
  },
  container: {
    flex: 1,
    backgroundColor: '#fff',
    fontSize: 10,
    marginLeft: 10,
    marginTop: 3
  },
  contentContainer: {
    paddingTop: 3
  },
});

Hey @bakthavatchalam.g,

If your project is on SDK32, you can longer use import Expo from 'expo'. You’ll have to either use import {Contacts} from 'expo' or import * as Expo from 'expo'.

Be sure to read the blog posts when upgrading or starting a new project with new SDK version! You can read about the breaking changes here: Expo SDK v32.0.0 is now available | by Eric Samelson | Exposition

Cheers,

Adam

Dear Adam,

Thank you it works now.

Glad to hear it!