fix: ensure firmware version is tracked in Device Connected Mixpanel event#4758
fix: ensure firmware version is tracked in Device Connected Mixpanel event#4758
Conversation
…l event The Device Connected event already included btDevice.toJson() which contains firmwareRevision, but it was always stale or 'Unknown' due to timing issues: - setConnectedDevice was void async so getDeviceInfo() couldn't be awaited - The early return path in getDeviceInfo() skipped saving to SharedPreferences Changes: - Change setConnectedDevice to Future<void> so callers can await it - Await setConnectedDevice before firing the Mixpanel event in both connection paths - Persist pairedDevice to SharedPreferences on the early return path in getDeviceInfo() Closes #4228 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request aims to resolve a timing issue where the Device Connected Mixpanel event was being sent with stale firmware information. The changes correctly make setConnectedDevice awaitable and ensure it's awaited before the event is fired. This allows for the device information, including the firmware version, to be fetched and persisted. However, I've identified a critical race condition in how the device information is saved to SharedPreferences. The current implementation uses a synchronous setter for an asynchronous operation, which could result in the Mixpanel event still capturing stale data, thereby undermining the intended fix. My review includes a specific comment and code suggestion to address this, aligning with best practices for provider state management and the use of existing helper functions.
|
Hey @krushnarout, sorry about the delay on this — @beastoin doesn't have bandwidth to review it right now and doesn't have any plans to in the near future. @aaravgarg, could you take a look and make the call on this one? Feel free to approve and merge if it looks good to you. Thanks both! |
|
Hey 👋 — thanks for putting this together! Before we can review, could you share a quick live demo (screenshot, screen recording, or terminal output) showing this working on your local or dev environment? In the AI era, writing code is the easy part — what really makes a PR stand out is proof that it works end-to-end. A short video or even a screenshot goes a long way in helping reviewers feel confident about merging. Feel free to update this PR whenever you have something to show. Thanks! 🙏 |
beastoin
left a comment
There was a problem hiding this comment.
Review by @ryo (community PR reviewer)
The approach is correct — making setConnectedDevice awaitable so firmware version is fetched before the Mixpanel event fires.
Code looks good, but two items remain before this can be approved:
-
Demo evidence still needed — @beastoin requested a screenshot/video showing the correct firmware version appearing in the Mixpanel event (Feb 19). Without evidence this works end-to-end, we can't approve.
-
Gemini flagged a race condition with SharedPreferences in the early-return path of
getDeviceInfo()— worth addressing or explaining why it's not an issue.
@krushnarout — are you still planning to add demo evidence? Happy to help if you need anything.
| Future getDeviceInfo() async { | ||
| if (connectedDevice != null) { | ||
| if (pairedDevice?.firmwareRevision != null && pairedDevice?.firmwareRevision != 'Unknown') { | ||
| SharedPreferencesUtil().btDevice = pairedDevice!; |
There was a problem hiding this comment.
not sure why we need to do this here? Is this part of the fix?
There was a problem hiding this comment.
yes, without it it would return immediately without saving to SharedPreferences. So deviceConnected() would still read the stale firmware version from there
…event (BasedHardware#4758) ## Summary - The `Device Connected` Mixpanel event already included `btDevice.toJson()` which contains `firmwareRevision`, but the value was always stale or `'Unknown'` due to timing issues - `setConnectedDevice` was `void async`, so `getDeviceInfo()` (which fetches firmware over BLE) could never be awaited — the Mixpanel event fired before firmware was fetched - The early-return path in `getDeviceInfo()` (when firmware was already known) skipped saving to SharedPreferences, so the Mixpanel event read old persisted data ### Changes - Changed `setConnectedDevice` from `void` to `Future<void>` so callers can await it - `await setConnectedDevice()` in both connection paths before firing `MixpanelManager().deviceConnected()` - Persist `pairedDevice` to SharedPreferences on the early-return path in `getDeviceInfo()` Closes BasedHardware#4228 ## Test plan - [ ] Connect a device and verify the `Device Connected` Mixpanel event contains the correct `firmwareRevision` value (not `'Unknown'`) - [ ] Reconnect a device that already has cached firmware info and verify the event still has the correct firmware version - [ ] Verify no regression in device connection flow timing 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
Device ConnectedMixpanel event already includedbtDevice.toJson()which containsfirmwareRevision, but the value was always stale or'Unknown'due to timing issuessetConnectedDevicewasvoid async, sogetDeviceInfo()(which fetches firmware over BLE) could never be awaited — the Mixpanel event fired before firmware was fetchedgetDeviceInfo()(when firmware was already known) skipped saving to SharedPreferences, so the Mixpanel event read old persisted dataChanges
setConnectedDevicefromvoidtoFuture<void>so callers can await itawait setConnectedDevice()in both connection paths before firingMixpanelManager().deviceConnected()pairedDeviceto SharedPreferences on the early-return path ingetDeviceInfo()Closes #4228
Test plan
Device ConnectedMixpanel event contains the correctfirmwareRevisionvalue (not'Unknown')🤖 Generated with Claude Code