Troubleshooting
Common integration issues and their fixes.
customEndpoints rejected
Cause: customEndpoints were passed while using production, sandbox, or staging.
Fix: Only pass customEndpoints with EixamEnvironment.custom.
initialSession.appId mismatch
Cause: The bootstrap appId and the provided signed session appId do not match.
Fix: Make both values identical.
Signing flow confusion
Cause: The mobile app is trying to hold the app secret or compute userHash locally.
Fix:
- Keep the app secret on the partner backend only
- Generate or obtain
userHashon the backend forappId+externalUserId - Pass the resulting signed session to the mobile app
- Perform all signing within the partner backend
Realtime URI looks non-WebSocket
Cause: The public field is named websocketUrl, but the configured broker may use a different transport scheme.
Fix: This is expected. Depending on environment and client transport, the broker URI may be ssl://, tls://, tcp://, ws://, or wss://.
Bootstrap did not request permissions
This is expected behavior. Permission requests remain explicit host-app actions — the SDK does not trigger them on its own.
Bootstrap did not pair a device
This is expected behavior. Device pairing and connection remain explicit host-app decisions.
SDK packages expose different APIs
Cause: eixam_connect_flutter, eixam_connect_core, and eixam_connect_ui were resolved from different commits/tags.
Fix: Pin every Eixam Git dependency to the same immutable release ref, run flutter clean, fetch packages again, and reinstall the app when native plugin dependencies changed.
Firmware check stays on “checking”
Cause: A live device refresh is slow/unreachable, or host UI blocks the entire card while waiting for a check.
Fix:
- Keep the rest of the Devices screen usable.
- Show the last known non-terminal result immediately when your product caches one, then revalidate in the background.
- Apply a host-side timeout to presentation if needed, but do not start from stale release eligibility.
- Retry after BLE command readiness and use
getBleDiagnostics()/getDeviceCommandChannelStatus()for support evidence.
The SDK bounds its live status refresh and falls back to known device status, but the host must still avoid an indefinite loading-only screen. See Firmware Updates / OTA.
OTA reaches 100% but does not complete
Upload percentage is not installed-version verification. Keep listening for reconnecting and verifyingInstalledVersion. Only completed is success.
If the terminal result is recoveryRequired, use the approved recovery workflow. Do not automatically start a second normal update while the device may be in its DFU bootloader.
Device volume changed after OTA
The device MCU reboot can reset firmware-memory buzzer values. Once OTA is completed and the normal command channel is ready, reapply host-persisted notification and SOS volume. Preserve an intentional 0 value; only use a fallback if the user has no saved preference.
LoRa region prompt never appears
Check, in order:
- Signed session and API connectivity.
- Location permission/service and an authoritative current location.
- Connected device and command-channel readiness.
- Backend country resolution and country/device config availability.
- Whether the device already reports the target region.
- Whether an active safety flow or OTA session deferred detection/apply.
Detection-only skip outcomes normally remain invisible. Inspect getDeviceCountryConfigStatus() or SdkOperationalDiagnostics.deviceCountryConfig in support tooling.
Region apply fails or keeps asking
- Call apply only for the latest
updateAvailablestate and after explicit confirmation. - Show retry only when
canRetryis true. skippedFirmwareUnsupportedmeans the device did not adopt the region. Do not loop reboots; update firmware or use the support path.- A different connected device invalidates the pending plan; run a new check for that device.
See LoRa Radio Region for every outcome.
Protection readiness is blocked
Inspect each of the following:
- Session availability
- Paired/connected device state
- Bluetooth enabled state
- Location permission
- Notification permission
- Platform capability readiness
iOS Protection coverage remains partial
This can be expected depending on current iOS runtime ownership support. See iOS Integration.
Realtime appears incomplete
Current realtime may depend on backend protocol maturity. Use runtime diagnostics and the agreed backend transport behavior as the source of truth.
MQTT auth fails after copying HTTP headers
Cause: MQTT auth is being treated like HTTP auth or old MQTT 5 User Properties.
Fix:
| Transport | Auth |
|---|---|
| HTTP | Authorization: Bearer <userHash> |
| MQTT username | sdk:<appId>:<externalUserId> |
| MQTT password | <userHash> (no Bearer prefix) |