Summary
On Android, flutter_contacts 2.3.1 silently drops birthday events when ContactsContract.CommonDataKinds.Event.START_DATE is stored in ISO 8601 basic form (yyyyMMdd) rather than the dashed form (yyyy-MM-dd).
This was reproduced on an Oppo Find N5 running ColorOS. The system Contacts app displays the birthday correctly, but both FlutterContacts.getAll(properties: {ContactProperty.event}) and the contact picker return the contact without its birthday.
This is related to #107, but this case has a full year and a confirmed cause in the current Android parser.
Reproduction
-
On the affected device, save a contact with a full Gregorian birthday in the system Contacts app.
-
Grant READ_CONTACTS.
-
Read contacts with:
final contacts = await FlutterContacts.getAll(
properties: {ContactProperty.event},
);
-
Compare the result with a direct, read-only query of Android's Contacts Data table for the same event row.
The direct query shows a standard birthday event row:
- mimetype:
vnd.android.cursor.item/contact_event
data2 = 3 (TYPE_BIRTHDAY)
data3 = NULL
data1: eight digits in yyyyMMdd form (real value redacted; synthetic example: 19780310)
The system Contacts app reports 1 birthday. The plugin reports 0 date events.
Expected result
The birthday should be returned as an Event with its year, month, day, and birthday label.
Actual result
The row is silently omitted.
Confirmed cause
In android/src/main/kotlin/co/quis/flutter_contacts/crud/models/properties/Event.kt, Event.fromCursor accepts only:
A yyyyMMdd value matches neither regex, so the parser produces null month/day values and returns null. The event never crosses the platform channel.
Because the contact picker uses the same parser, picker birthday prefill is affected as well.
Suggested fix
Accept ISO-basic full dates (yyyyMMdd) in addition to the existing extended formats, with unit coverage for both. More generally, preserving or explicitly reporting unrecognized non-null date values would make future OEM-specific formats easier to diagnose than silently dropping the entire event.
Environment
flutter_contacts: 2.3.1
- Flutter 3.44.4
- Dart 3.12.2
- Android device: Oppo Find N5
- OS: ColorOS
Summary
On Android,
flutter_contacts2.3.1 silently drops birthday events whenContactsContract.CommonDataKinds.Event.START_DATEis stored in ISO 8601 basic form (yyyyMMdd) rather than the dashed form (yyyy-MM-dd).This was reproduced on an Oppo Find N5 running ColorOS. The system Contacts app displays the birthday correctly, but both
FlutterContacts.getAll(properties: {ContactProperty.event})and the contact picker return the contact without its birthday.This is related to #107, but this case has a full year and a confirmed cause in the current Android parser.
Reproduction
On the affected device, save a contact with a full Gregorian birthday in the system Contacts app.
Grant
READ_CONTACTS.Read contacts with:
Compare the result with a direct, read-only query of Android's Contacts Data table for the same event row.
The direct query shows a standard birthday event row:
vnd.android.cursor.item/contact_eventdata2 = 3(TYPE_BIRTHDAY)data3 = NULLdata1: eight digits inyyyyMMddform (real value redacted; synthetic example:19780310)The system Contacts app reports 1 birthday. The plugin reports 0 date events.
Expected result
The birthday should be returned as an
Eventwith its year, month, day, and birthday label.Actual result
The row is silently omitted.
Confirmed cause
In
android/src/main/kotlin/co/quis/flutter_contacts/crud/models/properties/Event.kt,Event.fromCursoraccepts only:yyyy-MM-dd--MM-ddA
yyyyMMddvalue matches neither regex, so the parser produces null month/day values and returnsnull. The event never crosses the platform channel.Because the contact picker uses the same parser, picker birthday prefill is affected as well.
Suggested fix
Accept ISO-basic full dates (
yyyyMMdd) in addition to the existing extended formats, with unit coverage for both. More generally, preserving or explicitly reporting unrecognized non-null date values would make future OEM-specific formats easier to diagnose than silently dropping the entire event.Environment
flutter_contacts: 2.3.1