Zum Hauptinhalt springen

Capacitor Alternative zu Capacitor Community Contacts

Eine Alternative zum @capacitor-community/contacts Plugin: Kontakte, Gruppen, Pagination und Permission-free Picking aktualisiert – inklusive vollständiger Migrationsanleitung.

Capacitor Alternative zu Capacitor Community Contacts

Wenn du eine Capacitor Community Contacts Alternative suchst, ist der vollständigste Drop-in-Replacement: @capgo/capacitor-contacts. Es deckt alles ab, was @capacitor-community/contacts bietet (Lesen, Erstellen, Löschen und Auswählen von Kontakten) und ermöglicht das Aktualisieren eines Kontakts ohne ID-Änderung, Pagination, Gruppen, Accounts, native Kontakt-Screens sowie permission-freies Picking auf Android – entscheidend für die Google Play Contacts Policy 2027. Dieser Guide vergleicht beide und bildet jeden Call ab, damit du die Migration an einem Nachmittag erledigst.

Warum nach einer Alternative suchen?

@capacitor-community/contacts wird gepflegt und hat ein Capacitor 8 Release. Für einfache Read- und Create-Flows ist es eine gute Wahl. Teams wachsen meist aus folgenden Gründen darüber hinaus:

  • Keine Update-Methode. Du kannst Kontakte erstellen und löschen, aber nicht bearbeiten. Löschen und Neuerstellen vergibt eine neue ID, was alle gespeicherten Referenzen bricht und Daten verlieren kann, die das Plugin nicht liest.
  • Keine Pagination. getContacts gibt das gesamte Adressbuch in einem Call zurück. Auf einem Gerät mit 5.000 Kontakten und Fotos ist das langsam und speicherintensiv.
  • Picking benötigt auf Android die Permission. Das Android- pickContact fordert die Contacts-Permission an, bevor der Picker geöffnet wird, und liest den Kontakt dann aus dem Adressbuch. Unter Google Play Richtlinie zu Kontaktberechtigungen, können Apps, die auf Android 17 abzielen, nur READ_CONTACTS für Kernfunktionen.
  • Keine Gruppen, Accounts oder nativen Screens. Keine Möglichkeit, Gruppen aufzulisten, den Account für neue Kontakte zu wählen oder das System-Formular „Neuer Kontakt“ zu öffnen.

Feature-Vergleich

Feature @capacitor-community/contacts 8.0 @capgo/capacitor-contacts 8.1
Einzelne / alle Kontakte lesen getContact, getContacts getContactById, getContacts
Feldauswahl projection Objekt fields Array
Pagination Nein limit, offset
Kontakte zählen Nein countContacts
Erstellen createContact createContact
Vor Ort aktualisieren Nein updateContactById
Löschen deleteContact deleteContactById
Einen Kontakt auswählen pickContact pickContact
Mehrere auswählen Nein pickContacts({ multiple: true })
Telefon/E-Mail/Adresse ohne Berechtigung abrufen Nein pickContacts({ property })
Gruppen Nein getGroups, getGroupById, createGroup, deleteGroupById
Accounts Nein getAccounts
Native Create / View / Edit Screens Nein displayCreateContact, displayContactById, displayUpdateContactById
Getrennte Lese- und Schreibberechtigungen Nein (einzelner Alias) readContacts, writeContacts
iOS Limited Access Status limited limited
Einstellungen öffnen Nein openSettings

Installieren

bun add @capgo/capacitor-contacts
bunx cap sync

Das Plugin fügt keine Berechtigungen zum Android Manifest hinzu. Füge nur das hinzu, was du wirklich nutzt:

<!-- Needed for getContacts, getContactById, countContacts, groups, accounts -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- Needed for createContact, updateContactById, deleteContactById, groups writes -->
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

On iOS, add NSContactsUsageDescription zu Info.plist falls du das Adressbuch liest oder beschreibst. Für die Auswahl (Picking) ist dies nicht nötig.

Migrationsleitfaden, Schritt für Schritt

Berechtigungen

// Before
import { Contacts } from '@capacitor-community/contacts';
const perm = await Contacts.requestPermissions();
if (perm.contacts !== 'granted') return;

// After
import { CapacitorContacts } from '@capgo/capacitor-contacts';
const status = await CapacitorContacts.requestPermissions({ permissions: ['readContacts'] });
if (status.readContacts !== 'granted' && status.readContacts !== 'limited') {
  await CapacitorContacts.openSettings();
  return;
}

Ab iOS 18 können Nutzer nur einem Teil der Kontakte Zugriff gewähren. Das Plugin meldet dies als limited. Behandle dies als erteilt und verlasse dich nur auf die freigegebenen Kontakte.

Alle Kontakte lesen

// Before: whole address book, projection object
const { contacts } = await Contacts.getContacts({
  projection: { name: true, phones: true, emails: true },
});
const first = contacts[0];
console.log(first.name?.display, first.phones?.[0]?.number);

// After: fields array, paginated
const pageSize = 200;
let offset = 0;
for (;;) {
  const { contacts } = await CapacitorContacts.getContacts({
    fields: ['displayName', 'givenName', 'familyName', 'phoneNumbers', 'emailAddresses'],
    limit: pageSize,
    offset,
  });
  render(contacts);
  if (contacts.length < pageSize) break;
  offset += pageSize;
}

declare function render(list: unknown[]): void;

Nutze countContacts() zuerst, falls du einen Fortschrittsbalken anzeigen möchtest.

Einen Kontakt lesen

// Before
const { contact } = await Contacts.getContact({
  contactId: id,
  projection: { name: true, phones: true },
});

// After
const { contact } = await CapacitorContacts.getContactById({
  id,
  fields: ['displayName', 'phoneNumbers'],
});
if (!contact) console.log('Not found');

Kontakt erstellen

// Before
const { contactId } = await Contacts.createContact({
  contact: {
    name: { given: 'Ada', family: 'Lovelace' },
    phones: [{ type: PhoneType.Mobile, number: '+44 20 7946 0000' }],
    emails: [{ type: EmailType.Work, address: 'ada@example.com' }],
  },
});

// After
const { id } = await CapacitorContacts.createContact({
  contact: {
    givenName: 'Ada',
    familyName: 'Lovelace',
    phoneNumbers: [{ type: 'MOBILE', value: '+44 20 7946 0000' }],
    emailAddresses: [{ type: 'WORK', value: 'ada@example.com' }],
  },
});

displayName ist im Capgo Plugin schreibgeschützt. Schreibe givenName und familyName, und das Gerät formatiert den Anzeigenamen.

Kontakt aktualisieren (neu)

await CapacitorContacts.updateContactById({
  id,
  contact: {
    givenName: 'Ada',
    familyName: 'King',
    jobTitle: 'Analyst',
    phoneNumbers: [{ type: 'MOBILE', value: '+44 20 7946 0000' }],
  },
});

Die ID bleibt gleich, sodass alle gespeicherten Referenzen weiterhin funktionieren. Lies den Kontakt zuerst und sende die Felder zurück, die du behalten möchtest, um nichts versehentlich zu löschen.

Wenn der Nutzer selbst editieren soll, öffne den System-Editor:

await CapacitorContacts.displayUpdateContactById({ id });

Kontakt löschen

// Before
await Contacts.deleteContact({ contactId: id });

// After
await CapacitorContacts.deleteContactById({ id });

Kontakt auswählen

// Before: requests the contacts permission on Android first
const { contact } = await Contacts.pickContact({
  projection: { name: true, phones: true },
});

// After: one phone number, no permission on Android or iOS
import { ContactProperty } from '@capgo/capacitor-contacts';

const { contacts } = await CapacitorContacts.pickContacts({
  property: ContactProperty.PhoneNumber,
});
const phone = contacts[0]?.phoneNumbers?.[0]?.value;

Wenn du den vollständigen Datensatz aus dem Picker benötigst, rufe pickContact() ohne propertyauf. Bei Android wird der vollständige Kontakt nur zurückgegeben, wenn READ_CONTACTS wurde erteilt.

Field-Mapping

Community-Payload Capgo Contact
contactId id
name.display displayName (schreibgeschützt)
name.given / middle / family givenName / middleName / familyName
name.prefix / suffix namePrefix / nameSuffix
organization.company organizationName
organization.jobTitle jobTitle
birthday { day, month, year } birthday { day, month, year }
note note
phones[].number phoneNumbers[].value
emails[].address emailAddresses[].value
urls[] (Strings) urlAddresses[].value
postalAddresses[].region / postcode postalAddresses[].state / postalCode
image.base64String photo (Base64-String)

Auch die Typen ändern sich: Das Capgo Plugin nutzt Großbuchstaben wie 'MOBILE', 'HOME', 'WORK' für Telefonnummern und E-Mails.

Schrittweise pro Screen migrieren

Die beiden Plugins registrieren sich unter unterschiedlichen nativen Namen (Contacts und CapacitorContacts), sodass sie parallel installiert werden können, während du die Aufrufstellen migrierst. Ein kleiner Adapter hält den Rest deiner App unverändert:

import { CapacitorContacts } from '@capgo/capacitor-contacts';

export interface AppContact {
  id: string;
  name: string;
  phones: string[];
}

export async function listContacts(limit = 200, offset = 0): Promise<AppContact[]> {
  const { contacts } = await CapacitorContacts.getContacts({
    fields: ['displayName', 'phoneNumbers'],
    limit,
    offset,
  });
  return contacts.map((c) => ({
    id: c.id ?? '',
    name: c.displayName ?? '',
    phones: (c.phoneNumbers ?? []).map((p) => p.value),
  }));
}

Sobald die letzte Aufrufstelle migriert wurde, entferne das Community-Plugin und führe bunx cap sync, und prüfe das zusammengeführte Android Manifest, um sicherzustellen, dass nur die benötigten Berechtigungen verbleiben.

Fehlerbehebung

getContacts gibt auf iOS eine leere Liste zurück. Der Nutzer hat nur begrenzten Zugriff gewährt und keine Kontakte geteilt oder den Zugriff abgelehnt. Prüfe readContacts und biete openSettings().

Erstellter Kontakt wird in einem bestimmten Account auf Android nicht angezeigt. Übergib einen account (aus getAccounts()) in dem Kontakt, den du erstellst.

Fotos machen Listen langsam. Nicht anfragen photo in Listenansichten. Lade sie mit getContactById wenn der User einen Kontakt öffnet.

Play Console Warnungen READ_CONTACTS. Invite- und Share-Flows verschieben nach pickContacts({ property }) und die Permission entfernen, falls sie nicht mehr benötigt wird.

Veröffentlichen

Plugins zu tauschen ist eine Native-Änderung und erfordert einen Store-Build. Capgo Build kann iOS- und Android-Builds in der Cloud erstellen. Danach sind Fixes für deine Kontakt-Screens reines JavaScript und können via Capgo Live Updatesausgeliefert werden. Das vollständige API findest du im Contacts Plugin Docs.

Live-Updates für Capacitor-Apps

Wenn ein Bug im Web-Layer live ist, rollst du den Fix über Capgo aus, statt Tage auf die App-Store-Freigabe zu warten. Nutzer bekommen das Update im Hintergrund, während native Änderungen weiter den normalen Review-Prozess durchlaufen.

Neuestes aus unserem Blog

Capgo bietet dir die besten Insights für eine wirklich professionelle Mobile App.