Skip to content

fix: tolerate empty deepLinkData object in InstallResponse - #7

Merged
onamfc merged 2 commits into
mainfrom
fix/install-response-empty-deep-link-data
Sep 10, 2026
Merged

fix: tolerate empty deepLinkData object in InstallResponse#7
onamfc merged 2 commits into
mainfrom
fix/install-response-empty-deep-link-data

Conversation

@onamfc

@onamfc onamfc commented Aug 15, 2026

Copy link
Copy Markdown
Member

Ports the iOS SDK fix (mobile-sdk-ios#4) to Flutter. The bug was reported against iOS, but Flutter has the same defect.

Problem

The install endpoint returns deepLinkData: {} rather than null for organic (unattributed) installs:

{
  "installId": "<some_id>",
  "attributed": false,
  "confidenceScore": 0,
  "matchedFactors": [],
  "deepLinkData": {}
}

DeepLinkData.shortCode is required, so the generated DeepLinkData.fromJson threw a TypeError on json['shortCode'] as String. That happened inside InstallResponse.fromJson, so the whole response failed to parse and initialize() threw for every organic install — not just the deep link part of it.

Fix

deepLinkData now parses through @JsonKey(fromJson: _deepLinkDataFromJson): anything that isn't a map, or that DeepLinkData.fromJson rejects, becomes null — so {} and a short-code-less object mean "no deep link", the same as null and absent. The failure is logged when debug logging is on rather than rethrown, since a deep link the SDK can't parse is never worth aborting attribution over.

Deliberately unchanged:

  • DeepLinkData.shortCode stays required. A deep link without a short code isn't routable, and loosening it would be a breaking change for anything reading it.
  • Top-level fields stay strict. installId, attributed, confidenceScore, and matchedFactors are always returned, and installId is required for the SDK to work at all.
  • toJson is untouched — the generated serializer still emits deepLinkData?.toJson().

install_response.g.dart is regenerated with build_runner; the only change is the one call site.

Fixing this SDK-side rather than only backend-side is what actually unblocks integrators: self-hosted deployments and already-deployed backends will keep sending {}, and the SDK has to survive that.

Tests

install_response_test.dart gains coverage for {}, null, and short-code-less deepLinkData, the attributed path, and a missing-required-field failure. Full suite: 106 tests passing, flutter analyze clean.

The install endpoint returns `deepLinkData: {}` rather than `null` for
organic (unattributed) installs. `DeepLinkData.shortCode` is required, so
`InstallResponse.fromJson` threw a TypeError and `initialize()` failed for
every organic install.

Parse `deepLinkData` leniently: an empty object — or any payload without a
usable short code — is now treated as "no deep link" (null), matching the
`null` and absent cases. The failure is logged when debug logging is on
instead of failing the whole response, since a deep link we cannot parse is
never worth aborting attribution over. Required top-level fields stay strict.

Ports the iOS SDK fix (LinkForty/mobile-sdk-ios#4) to Flutter.
@onamfc
onamfc merged commit fe6df33 into main Sep 10, 2026
4 checks passed
@onamfc
onamfc deleted the fix/install-response-empty-deep-link-data branch September 10, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant