Skip to content

Name update writes to wrong rawContactId on contacts with multiple raw contacts (e.g. Google + WhatsApp) #236

@rajivm1991

Description

@rajivm1991

Bug Description

When updating a contact's name fields (first, middle, last) on Android, the changes do not persist if the contact has multiple raw contacts (e.g. Google account + WhatsApp).

Root Cause

The Dart Name model does not expose a metadata field (unlike Phone, Email, etc.). As a result, when Dart serializes the contact for update, the name's rawContactId is not included in the JSON payload sent to Kotlin.

On the Kotlin side, getPrimaryRawContactIdForUpdate calls getRawContactIdWithMostProperties, which counts properties per raw contact using their metadata. Because contact.name?.metadata is always null (never round-tripped from Dart), the name's rawContactId contributes zero to the count. The "winner" is determined solely by phone/email/etc counts — which often picks the WhatsApp raw contact.

Name.toUpdateOperations(rawContactId) then:

  1. Deletes StructuredName from the WhatsApp raw contact (which had none)
  2. Inserts new StructuredName into the WhatsApp raw contact

Meanwhile, the Google raw contact's StructuredName is untouched. Android's aggregation prefers the Google account for names, so the old name persists.

Reproduction

  1. Have a contact with both a Google account raw contact and a WhatsApp raw contact
  2. Call FlutterContacts.get(id, properties: ContactProperties.all) — fetch succeeds, name is correct
  3. Modify contact.name (e.g. clear middle name)
  4. Call FlutterContacts.update(contact) — returns successfully
  5. Re-fetch the contact — name is unchanged

Logcat evidence (name.middle being cleared, verify immediately after update):

[SAVE] fresh name: first=Jegadesan S. middle=K. last=Auditor
[SAVE] updated name: first=Jegadesan S. middle= last=Auditor
[SAVE] update complete for id=76954
[SAVE] verify name: first=Jegadesan S. middle=K. last=Auditor   ← unchanged
[SAVE]   rawContact: id=518  account=rajiv.m1991@gmail.com type=com.google
[SAVE]   rawContact: id=76866 account=WhatsApp type=com.whatsapp

Expected Fix

Add metadata field to the Dart Name class (same as Phone, Email, Address, etc. already have). This allows the name's rawContactId to round-trip through the method channel, so getRawContactIdWithMostProperties correctly counts the name's raw contact and picks the right one for the update.

// Name class should include:
final PropertyMetadata? metadata;

And in copyWith:

Name copyWith({
  ...
  PropertyMetadata? metadata,
}) => Name(
  ...
  metadata: metadata ?? this.metadata,
);

Environment

  • flutter_contacts: 2.2.0
  • Android (tested on device with Google account + WhatsApp contacts)
  • Contacts with 2 raw contacts: com.google + com.whatsapp

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions