Bird

Keep push device registrations current

A Push destination represents an app installation or browser subscription. It is not a customer ID. Keep permission, customer identity, notification preference and the current destination separate so a device change cannot silently become an account change.

Store the relationship

Record your application/environment, installation, current customer association and last registration update. Treat destination tokens as private. One customer can have several installations; each installation can change users. Bird stores Push destinations as contact identifiers with key push-{channelId} and a gateway-prefixed value such as web:{token} or firebase:{token}.
For account-specific web content, establish identity using a signed claim issued by your authenticated server, then subscribe:
Code example
// signedIdentity is issued for the authenticated session by your server.
await Bird.contact.identify({ strategy: "SignedIdentityClaims", signedIdentity });
const token = await Bird.pushNotifications.subscribe();
The server must derive the customer from its session, not sign an arbitrary ID supplied by the browser. Follow signed identity. Anonymous registration is useful for a controlled test or an anonymous experience; do not infer a customer account from possession of its token.
Browser/OS notification permission controls presentation. A customer's marketing preference controls whether they want Push campaigns. If they explicitly opt into those campaigns, the Web SDK supports:
Code example
await Bird.contact.putAttributes({ subscribedPush: true });
Do not set this merely because the OS permission is granted. Preserve an existing refusal and implement opt-out with the corresponding preference update. See campaign subscriptions.

Refresh a changed token

Forward APNs registration callbacks and keep the Bird Android messaging service's token handling connected. The SDK must receive new registration data after a reinstall or token rotation; do not freeze the first token in an application database. If your server keeps a destination index, update it with the current association and retire the old value. FCM's token guidance describes freshness and invalid registrations.
On web, Bird.pushNotifications.subscribe() returns the opaque token without the web: prefix. The SDK replaces an existing browser subscription during a new subscribe call and updates the contact identifier. Call it deliberately from your subscription flow, not on every page render. Keep the returned token and its channel-scoped key available for installation cleanup while that identity is active.

Handle sign-out and account switching

Detach the current installation from the old customer while that customer's Bird identity is still active. Resetting local identity alone does not remove the remote identifier or cancel the browser subscription. This Web SDK example uses the token saved after successful registration:
Code example
async function detachThisBrowser(pushChannelId, currentToken) {
  // Run before discarding the old customer's Bird identity.
  await Bird.contact.deleteIdentifier({
    key: `push-${pushChannelId}`,
    value: `web:${currentToken}`,
  });
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.getSubscription();
  if (subscription && !(await subscription.unsubscribe())) {
    throw new Error("Browser subscription cleanup needs reconciliation");
  }
  Bird.contact.reset({ anonymousId: "refresh" });
}
This is installation cleanup, so it does not change the customer's contact-wide subscribedPush preference or disable another device. If cleanup fails or the device is offline, retain a cleanup task on your backend and suppress account-specific sends to the unresolved installation. Complete account sign-out without leaving the previous session usable; reconcile the remote association before enabling a new customer's private notifications. After the next login, identify the new customer and obtain a current registration.
For native apps, implement the equivalent installation-detachment flow against your contact integration before resetting identity. Do not assume a native reset() call retires the old destination. Test against your selected SDK version and use the contact APIs as the integration owner.

Retire invalid destinations

When a gateway reports an expired or invalid destination, Bird's Push worker removes that contact identifier and records a send failure. The customer and their other destinations remain separate. Also retire the stale value in your own destination index; obtain a fresh registration through the client before another useful send. Do not keep replaying the failed token.
A timeout or absent receipt is different: the original send may still have reached the device. Retain its message ID and reconcile its status. Permission denied, invalid token and unknown delivery require different recovery actions.

Verify the lifecycle

TestEvidence to retain
Permission deniedNo prompt loop or assumption of consent; the task remains accessible in the app.
Token changesThe new destination is associated with the intended customer; the obsolete one is retired.
Customer A logs out, B logs inA's private test message cannot reach that installation; B's destination is current.
Same customer on two devicesLogging out on one device does not silently opt the other out of campaigns.
Reinstallation or cleared browser storageNew identity/registration is reconciled instead of trusting the old local token.
Cleanup fails offlineUnresolved installation is excluded from private sends until cleanup is confirmed.

Related resources

Continue with the documentation, guides and examples for this topic. Resources are in English.

Get an implementation brief