Moving device tokens between push notification providers is not a simple database export. A token is issued for a particular app, device, push service, and environment, and it can change during the lifetime of an installation. A migration that copies records but does not account for token rotation, provider identifiers, or delivery behaviour can silently reduce reach.

The safest approach is a staged migration. Keep the existing delivery path working while the new provider begins registering devices and accepting sends. Measure the results, handle token changes continuously, and remove the old path only after the new system has demonstrated reliable coverage.

Start by defining what is being migrated

Before changing code, inventory the identifiers stored by your current system. These may include:

  • A native device token or push token
  • A provider-specific subscription or installation ID
  • An internal user ID
  • Device and platform information
  • Notification permissions and opt-in state
  • Tags, segments, or audience membership
  • The provider environment, such as development or production
  • Timestamps and the last known token update

Do not assume that a provider-specific ID is interchangeable with a native token. It may identify a subscription record rather than the token issued by Apple, Google, or a web push service. It may also be usable only within the provider that created it.

Define the source of truth for each field. For example, your product database might own the user relationship and preferences, while the client SDK owns the current push token and registration lifecycle. This distinction prevents an old export from overwriting a newer token during the migration.

Choose a migration strategy

There are three common patterns. The right choice depends on your traffic, release process, and tolerance for additional operational complexity.

Re-register devices with the new provider

The client application registers with the new provider after an app update or web deployment. The server then associates the resulting device record with the existing user.

This is usually the most reliable approach because the new provider receives a current token through its own supported registration flow. It does, however, depend on users opening or loading the updated client. Devices that do not update immediately will remain dependent on the old delivery path.

Import existing identifiers

Some migrations can import existing provider records or subscription IDs. This may reduce the time needed to reach inactive installations, but imported data still needs validation. An imported ID does not necessarily prove that the corresponding token is current or that it belongs to the expected provider environment.

With HoneyNotify, imported OneSignal subscription IDs can remain as device IDs when matching provider tokens later register. Matching can fail if the token rotates or if the token comes from another provider environment. Treat imported identifiers as migration aids, not permanent evidence that registration is complete.

Run both systems temporarily

A dual-run migration keeps the old provider active while the new provider is introduced. You can send through the old system for continuity, register devices with HoneyNotify, and gradually move traffic once coverage is acceptable.

Sending the same user-facing notification through both providers can create duplicates. Prefer a controlled split, such as routing selected cohorts through the new system, or use a notification ledger that records which provider handled each message. If both systems must send during an incident, make the operation explicit and idempotent rather than relying on timing.

Build the new registration path first

Before switching delivery, release the client changes needed for registration and token lifecycle handling. HoneyNotify client SDKs cover device registration, identity, token lifecycle, payload handling, and lifecycle events across iOS, Android, and Web Push.

The client should register or refresh its device record when the application or browser provides a token, when the user signs in or out, and when the SDK reports a token change. Registration should be safe to repeat. A repeated lifecycle event must update the existing device rather than create uncontrolled duplicates.

Associate devices with a stable application-level identity where appropriate. A user ID should not be confused with a device ID: one user can have multiple devices, and a device can change owners after logout. Define how logout, account switching, shared devices, and anonymous users are handled before production rollout.

Keep permission state separate from registration state. A device can be known to the service but unable to receive notifications because permission was denied, the browser subscription expired, or the operating system has restricted delivery.

Prepare the server-side send path

Once registrations are flowing, add the new server-side send integration without removing the existing one. HoneyNotify sends use POST /v1/notifications with a Bearer API key and an Idempotency-Key. A notification requires a title, body, and target.

Targets can address a device, user, tag, segment, or all enabled devices. Start with the narrowest target that supports your migration tests. Device-level tests help verify registration, while user- or segment-level tests reveal whether identity and audience data were migrated correctly.

Use idempotency consistently for retryable operations. Your application should generate and retain an idempotency key for one logical send, then reuse it when retrying that same operation. Do not create a new key for every network retry, or an uncertain response could result in multiple sends.

Keep provider credentials and routing decisions on the server. Do not place a server API key in a mobile application, browser bundle, or other client-distributed code. Record the logical notification ID, target type, provider selected, request outcome, and relevant timestamps so that delivery issues can be investigated without storing unnecessary personal data.

Roll out in stages

A migration is easier to control when registration and sending are deployed separately.

  • Add new client registration and lifecycle handling while the old provider remains active
  • Confirm that new and returning installations appear in the new system
  • Import eligible legacy identifiers, recording their source and import time
  • Compare the number of active users and devices represented by each provider
  • Route internal test accounts and a small production cohort through the new path
  • Expand by platform, application version, geography, or user cohort
  • Keep the old path available until the agreed exit criteria are met

Use feature flags or server-side routing rather than embedding an irreversible provider choice in the client. A server-side switch lets you pause expansion, return a cohort to the old path, or disable a problematic platform without waiting for an app-store review.

Your exit criteria should be specific. They might include successful registration for newly active installations, acceptable send error rates, correct identity and segmentation, verified logout behaviour, and an operational process for token updates. Avoid using only aggregate send counts; they can look healthy while one platform or application version is failing.

Monitor the failure modes that matter

Track registration and send metrics by platform, app version, provider environment, and migration cohort. Useful signals include:

  • Registration attempts and successful registrations
  • Token updates and removals
  • Devices associated with a user versus anonymous devices
  • Sends accepted, rejected, retried, and abandoned
  • Invalid or expired token responses
  • Duplicate notifications reported by testing or support
  • Time from client registration to first successful send
  • The proportion of traffic still using the old provider

A successful API request is not the same as a notification being displayed. Separate request acceptance, provider processing, device delivery, and application handling where your telemetry supports those distinctions. On the client, lifecycle and payload events can help identify whether a notification arrived but was filtered, malformed, or handled unexpectedly.

Pay particular attention to token rotation. A token that was valid when exported may be stale by the time it is used. The client must be able to send fresh token information back to the new system, and the server must not reintroduce an older exported value after that update.

Common migration mistakes

Treating tokens as permanent

Tokens can change after reinstallations, restores, permission changes, application updates, or provider events. Store the latest value and process lifecycle updates continuously.

Matching only on a user ID

A user-level match can hide multiple devices and can send to a device that has since signed out. Model the user-to-device relationship explicitly and test account switching.

Mixing environments

Development and production registrations are not interchangeable. Keep environment data separate and verify that imported records and newly registered tokens belong to the same environment as the send configuration.

Deleting the old provider too early

Removing the old registration or send path before the new client version is widely active creates a gap for users who have not launched the updated application. Retain a rollback route until coverage and behaviour are understood.

Sending through both providers without coordination

Dual writes can produce duplicate notifications and inconsistent preferences. Use a routing decision, a notification ledger, and idempotency rather than allowing independent workers to send the same event.

Assuming an import is proof of delivery

An imported identifier may be useful for matching, but it does not confirm permission, token freshness, application presence, or successful display. Validate the complete lifecycle with controlled tests.

A practical cutover checklist

Before the final switch, verify that:

  • New installations register with the new provider on every supported platform
  • Token refresh events update the correct device record
  • Anonymous, signed-in, signed-out, and switched-account states behave as designed
  • Imported identifiers are traceable and environment-specific
  • Server sends use protected credentials and stable idempotency keys
  • Routing can be changed without a new client release
  • Monitoring distinguishes registration, acceptance, delivery, and display failures
  • A rollback decision and owner are documented
  • The old provider is retained for the agreed transition period

Conclusion

A no-downtime device-token migration is primarily a lifecycle and routing project, not a one-time export. Register current devices with the new provider, treat imported identifiers cautiously, keep both delivery paths coordinated, and roll out using measurable cohorts. When token refresh, identity changes, retries, and rollback are designed from the beginning, the final provider switch becomes a controlled operational change rather than a risky cutover.