Skip to content

Fix TypeError when an Android inbox message carries a notification payload - #9

Open
fa0311 wants to merge 1 commit into
salesforce-marketingcloud:mainfrom
fa0311:fix/android-inbox-payload-map
Open

Fix TypeError when an Android inbox message carries a notification payload#9
fa0311 wants to merge 1 commit into
salesforce-marketingcloud:mainfrom
fa0311:fix/android-inbox-payload-map

Conversation

@fa0311

@fa0311 fa0311 commented Jul 19, 2026

Copy link
Copy Markdown

On Android, InboxUtils serializes notificationMessage.payload with JSONObject(map).toString(), so Dart receives a JSON string where NotificationMessage.fromJson expects a map and throws type 'String' is not a subtype of type 'Map<dynamic, dynamic>'. A single alert+inbox push in the inbox is enough to break getMessages() and the other getters entirely. iOS is unaffected (it doesn't emit notificationMessage).

The payload is now put as a JSONObject, and the Dart side accepts both shapes so apps aren't stuck if the native and Dart versions are briefly out of sync. Also removed a leftover debugPrint that dumped the full notification payload on every parse.

…, not a string

On Android, InboxUtils.NotificationMessage.toJson() serialized the push
payload with mapToJson(), which returns JSONObject(map).toString() - a
JSON-encoded String. After jsonDecode on the Dart side, json['payload']
was therefore a String, and NotificationMessage.fromJson's
Map<String, String>.from(json['payload']) threw
_TypeError: type 'String' is not a subtype of type 'Map<dynamic, dynamic>'.

Because _parseMessages and the onInboxMessagesChanged handler parse every
message inside a single map(), one inbox message carrying a
notificationMessage with a non-null payload (typical for combined
Alert+Inbox pushes) made getMessages, getReadMessages, getUnreadMessages
and getDeletedMessages reject and silently dropped inbox-change updates,
rendering the whole inbox unusable. iOS is unaffected since its
InboxUtility does not emit notificationMessage.

Fix:
- InboxUtils.kt now puts the payload as a JSONObject so the decoded
  structure reaching Dart is a Map, matching the declared Dart model. The
  now-unused mapToJson helper is removed.
- NotificationMessage.fromJson is tolerant of both wire shapes: it
  accepts payload as a Map or as a JSON-encoded String (decoded via
  jsonDecode), for robustness against older native layers.
- Tests cover both wire shapes: unit tests for
  NotificationMessage.fromJson and an end-to-end getMessages test through
  the method channel.

Also removes a stray debugPrint(json.toString()) from
NotificationMessage.fromJson (and the then-unused foundation import),
which dumped the full notification payload to the log on every parse.
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.

2 participants