How to add google calendar events to the Flutter event calendar?
In In this guide, I'll explain how to load Google Calendar events into the Flutter event calendar widget using OAuth authentication Client ID.
STEP 1: Add the required packages to your pubspec.yaml file:
dependencies: flutter: sdk: flutter syncfusion_flutter_calendar: ^18.3.40 intl: ^0.16.0 google_sign_in: ^4.4.6 googleapis_auth: ^0.2.11+1 googleapis: ^0.54.0 cupertino_icons: ^0.1.2
STEP 2: Create a sample and install the above packages in the sample. Now, need to get the SHA_1 key from Android folder. First open the Flutter project, then open the terminal and type the command in the terminal cd android. Now type the command ./gradlew signingReport to generate SHA_1 key.
Please find the SHA-1 Key value in terminal and copy the value.
STEP 3: Create a project in below google developers console link.
STEP 4: In Dashboard tab click “Enable APIS and services” and enable calendar API’s.
STEP 5: In Credential tab click the “Create Credential” option and click “OAuth client ID” option from the list.
STEP 6: Then specify the Application type, Package name, SHA-1 key (already copied from sample) value and create a project.
Application type: Android
Package name: Should be in AndroidManifest.xml file of the sample.
STEP 7: Call the GoogleSignIn method to authenticate Google users.
final GoogleSignIn _googleSignIn = GoogleSignIn( clientId: 'OAuth Client ID', scopes: <String>[ googleAPI.CalendarApi.CalendarScope, ], );
STEP 8: Google provides googleAPI.Event class which holds the details about the google events and use these API’s in override methods.
class GoogleDataSource extends CalendarDataSource { GoogleDataSource({List<googleAPI.Event> events}) { this.appointments = events; } @override DateTime getStartTime(int index) { final googleAPI.Event event = appointments[index]; return event.start.date ?? event.start.dateTime.toLocal(); } @override bool isAllDay(int index) { return appointments[index].start.date != null; } @override DateTime getEndTime(int index) { final googleAPI.Event event = appointments[index]; return event.endTimeUnspecified != null && event.endTimeUnspecified ? (event.start.date ?? event.start.dateTime.toLocal()) : (event.end.date != null ? event.end.date.add(Duration(days: -1)) : event.end.dateTime.toLocal()); } @override String getLocation(int index) { return appointments[index].location; } @override String getNotes(int index) { return appointments[index].description; } @override String getSubject(int index) { final googleAPI.Event event = appointments[index]; return event.summary == null || event.summary.isEmpty ? 'No Title' : event.summary; } }
STEP 9: To load the google events, create async method named as getGoogleEventsData() and get the data from google calendar using googleAPI.Event. Please find the following code snippet for the same.
Future<List<googleAPI.Event>> getGoogleEventsData() async { final GoogleSignInAccount googleUser = await _googleSignIn.signIn(); final GoogleAPIClient httpClient = GoogleAPIClient(await googleUser.authHeaders); final googleAPI.CalendarApi calendarAPI = googleAPI.CalendarApi(httpClient); final googleAPI.Events calEvents = await calendarAPI.events.list( "primary", ); Final List<googleAPI.Event> appointments = <googleAPI.Event>[]; if (calEvents != null && calEvents.items != null) { for (int i = 0; i < calEvents.items.length; i++) { final googleAPI.Event event = calEvents.items[i]; if (event.start == null) { continue; } appointments.add(event); } } return appointments; }
STEP 10: Using the FutureBuilder widget, you can display the google calendar data. Based on the Snapshot.data, you can load that google calendar events to the Flutter calendar.
child: FutureBuilder( future: getGoogleEventsData(), builder: (BuildContext context, AsyncSnapshot snapshot) { return Container( child: Stack( children: [ Container( child: SfCalendar( view: CalendarView.month, dataSource: GoogleDataSource(events: snapshot.data), monthViewSettings: MonthViewSettings( appointmentDisplayMode: MonthAppointmentDisplayMode.appointment), ), ), snapshot.data != null ? Container() : Center( child: CircularProgressIndicator(), ) ], )); }, ),