Skip to content

Migration rollout and rollback ​

Use this with the CallKeep or flutter_callkit_incoming mapping. Migration changes native lifecycle ownership, backend signaling and media startup as well as framework code. Keep the existing media provider unless you deliberately choose a separate media migration.

Audit the current call path ​

Record the file responsible for each task before changing it:

TaskWhat to findCallx destination
Push registrationWhich installation/user owns each token; refresh and sign-out handlingBackend installation registration plus native push setup
Incoming reportingNative push hooks, background handlers and foreground incoming screensNative ingress; one coordinated incoming presenter
Call identityBackend ID, UI ID, room ID and remote end lookupOne stable call ID across signaling, native commands and media mapping
System actionsAnswer, decline, hang-up, mute/hold handlersNative callbacks and typed commands; framework observes snapshots
MediaAll places that join/leave a roomOne adapter or native host-controlled media owner
RecoverySaved booleans, deferred events and reconnect decisionsNative snapshots/replay and backend reconciliation
BackendAccepted/cancelled/ended messages, retries and expiryAuthenticated signaling to ingress with idempotent backend handling

List unsupported requirements before replacing the stack: Callx currently allows one live call; caller-display updates and several provider adapters are still planned. Check status and roadmap, not just an API-name match.

Prepare the backend first ​

Add your own installation-level integration marker to backend registration, for example legacy or callx. This is application metadata you implement, not a Callx payload field. Keep token platform, account and app version alongside it.

Route one invitation format per installation. An old installation receives the old payload; a migrated installation receives the Callx payload. Do not send both reporting paths to the same installation: two native presenters can compete for one invitation. Token refresh, sign-out and app upgrades must refresh this routing information.

Preserve backend call IDs and terminal reasons. Repeated answer/end callbacks or network retries must not create another call or join another room. Implement backend retry and idempotency; a native committed action alone does not guarantee successful network delivery.

Check: old clients still ring and migrated clients receive only Callx invitations. A cancel that arrives before its invitation remains cancelled on the migrated installation.

Replace ownership in a development build ​

  1. Finish the relevant framework quick start and native bootstrap.
  2. Remove the old native presenter/push reporting hooks from the migrated build. Keep unrelated chat notifications and other Firebase consumers; forward non-call messages to their owner.
  3. Connect native answer/end work to the backend and wire media to one adapter/native owner.
  4. Replace framework event-based call state with snapshots. Use replay for durable event consumption rather than reproducing the old deferred-event queue.
  5. Keep Home until acceptance, then show the accepted-call screen. Reopening the screen after recovery must not call Answer or join media again.
  6. Register this build's installation for the new backend route only after its native setup works.

Do not switch call stacks halfway through a live call. Package removal and native configuration require a rebuilt binary; a remote UI flag cannot install a missing native implementation.

Validate old and new clients together ​

TrialExpected result
New caller → old receiver; old caller → new receiverBackend routes each installation correctly; call IDs and end signals still match
Foreground incomingOne incoming presenter; accepted-call overlay opens only after acceptance
Background/terminated-runtime answerNative acceptance and media startup work before framework UI loads
Remote cancel, expiry, duplicate inviteNo late second ring; terminal reason is retained
Answer followed by reload/process deathUI restores native state; no duplicate acceptance or media join
Sign-out/token refresh/app upgradePush registration and account generation belong to the current account
Video/minimize/PiPOne media owner, correct camera policy, same call after expanding

Use the full device checklist and record the exact build/device/OS. Test Android force-stop and vendor restrictions separately; iOS pushes require a physical iPhone.

Roll out gradually ​

Start with internal users and a small cohort of installations. Observe delivery-to-ring, answer-to-media connection, terminal cleanup and crash/recovery outcomes through your own application/backend diagnostics. The library does not supply hosted analytics.

Keep old-format backend support until supported old app versions have aged out. Separate presentation rollout from provider replacement so failures can be attributed to one change.

Roll back with matching client support ​

Stop enrolling new installations and keep routing existing builds to the stack actually inside them. Routing a Callx-only binary to a legacy payload will not restore the old SDK.

If the binary intentionally includes a tested legacy fallback, select its owner before a call and update backend registration together. Otherwise rollback needs a rebuilt app release. Drain live calls before switching owners. Verify token routing, single presenter and media cleanup again after rollback; retain both backend formats while mixed versions remain active.

Released under the MIT License. No telemetry, in the library or on this site.