I'm using Expo's Calendar API to create a calendar and events, but I'm getting the following error only on my real device when it works perfectly on the iOS simulator:
[Unhandled promise rejection: Error: Error: Calendar 'Expo Calendar' could not be saved: Error Domain=EKErrorDomain Code=17 "That account does notallow calendars to be added or removed." UserInfo={NSLocalizedDescription=That account does not allow calendars to be added or removed.}]
My code:
import React, { useEffect } from 'react';
import { View, Text, Button, Platform } from 'react-native';
import * as Calendar from 'expo-calendar';
export default function App() {
useEffect(() => {
(async () => {
const { status } = await Calendar.requestCalendarPermissionsAsync();
if (status === 'granted') {
const calendars = await Calendar.getCalendarsAsync();
console.log('Here are all your calendars:');
console.log({ calendars });
}
})();
}, []);
return (
<View
style={{
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'space-around',
}}>
<Text>Calendar Module Example</Text>
<Button title="Create a new calendar" onPress={createCalendar} />
</View>
);
}
const getDefaultCalendarSource = async () => {
const defaultCalendar = await Calendar.getDefaultCalendarAsync();
return defaultCalendar.source;
}
async function createCalendar() {
const defaultCalendarSource =
Platform.OS === 'ios'
? await getDefaultCalendarSource()
: { isLocalAccount: true, name: 'Expo Calendar' };
const newCalendarID = await Calendar.createCalendarAsync({
title: 'Expo Calendar',
color: 'blue',
entityType: Calendar.EntityTypes.EVENT,
sourceId: defaultCalendarSource.id,
source: defaultCalendarSource,
name: 'internalCalendarName',
ownerAccount: 'personal',
accessLevel: Calendar.CalendarAccessLevel.OWNER,
});
console.log(`Your new calendar ID is: ${newCalendarID}`);
}
The permission have been given to the calendar and all the calendars have "allowsModifications": true
, but can't understand why it says it's not allowed only on a real device.
I've tried modifying the default calendars to different source as following:
async function getDefaultCalendarSource() {
const calendars = await Calendar.getCalendarsAsync();
const defaultCalendars = calendars.filter(
each => each.source.name === 'Gmail' // or 'iCloud', 'Yahoo'
);
return defaultCalendars[0].source;
}
thinking that it may have to do with the source, but they result in the same error, "that account does not allow calendars to be added or removed."