From 0d0736b391d60569e22ca519ab0712fce8a9b6d7 Mon Sep 17 00:00:00 2001 From: Dillon Nys <24740863+dnys1@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:13:01 -0700 Subject: [PATCH] fix(push): Incorrect handling of simple alert (#3502) Fixes #3435. Simple alerts on iOS take the shape (see [docs](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html)): ```json { "aps": { "alert": "Message" } } ``` This case was not being handled in the deserializer (only the case where `alert` was a Map). --- .../push/push_notification_message.dart | 117 ++++++++++-------- .../test/push_notification_message_test.dart | 4 + .../test_data/fake_notification_messges.dart | 6 + 3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/packages/amplify_core/lib/src/types/notifications/push/push_notification_message.dart b/packages/amplify_core/lib/src/types/notifications/push/push_notification_message.dart index f3cd9aeb36..b8f7ba3167 100644 --- a/packages/amplify_core/lib/src/types/notifications/push/push_notification_message.dart +++ b/packages/amplify_core/lib/src/types/notifications/push/push_notification_message.dart @@ -21,57 +21,74 @@ class PushNotificationMessage }); factory PushNotificationMessage.fromJson(Map json) { - String? title; - String? body; - String? imageUrl; - String? deeplinkUrl; - String? goToUrl; - ApnsPlatformOptions? apnsOptions; - FcmPlatformOptions? fcmOptions; - - final data = (json['data'] as Map?) ?? {}; - final aps = json['aps'] as Map?; - if (aps != null) { - final alert = aps['alert'] as Map?; - if (alert != null) { - title = alert['title'] as String?; - body = alert['body'] as String?; - imageUrl = data['media-url'] as String?; - - if (data['pinpoint'] != null) { - final pinpointData = data['pinpoint'] as Map; - deeplinkUrl = pinpointData['deeplink'] as String?; - goToUrl = deeplinkUrl; - } - apnsOptions = ApnsPlatformOptions(subtitle: aps['subtitle'] as String?); - } - } else { - final action = json['action'] as Map?; - title = json['title'] as String?; - body = json['body'] as String?; - imageUrl = json['imageUrl'] as String?; - if (action != null) { - deeplinkUrl = action['deeplink'] as String?; - goToUrl = action['url'] as String?; - } - final fcmOptionsMap = json['fcmOptions'] as Map?; - if (fcmOptionsMap != null) { - fcmOptions = FcmPlatformOptions( - channelId: fcmOptionsMap['channelId'] as String?, - messageId: fcmOptionsMap['messageId'] as String?, + final data = (json['data'] as Map?) ?? const {}; + switch (json) { + // `aps` dictionary references: + // - https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification + // - https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html + case {'aps': final Map aps}: + final title = switch (aps) { + {'alert': final String alert} => alert, + {'alert': {'title': final String title}} => title, + _ => null, + }; + final body = switch (aps) { + {'alert': {'body': final String body}} => body, + _ => null, + }; + final imageUrl = data['media-url'] as String?; + final deeplinkUrl = switch (data) { + {'pinpoint': {'deeplink': final String deeplink}} => deeplink, + _ => null, + }; + final apnsOptions = ApnsPlatformOptions( + subtitle: switch (aps) { + {'alert': {'subtitle': final String subtitle}} => subtitle, + _ => null, + }, + ); + return PushNotificationMessage( + title: title, + body: body, + imageUrl: imageUrl, + deeplinkUrl: deeplinkUrl, + goToUrl: deeplinkUrl, + apnsOptions: apnsOptions, + data: data, + ); + default: + final title = json['title'] as String?; + final body = json['body'] as String?; + final imageUrl = json['imageUrl'] as String?; + final (deeplinkUrl, goToUrl) = switch (json['action']) { + {'deeplink': final String deeplink, 'url': final String url} => ( + deeplink, + url + ), + {'deeplink': final String deeplink} => (deeplink, null), + {'url': final String url} => (null, url), + _ => (null, null), + }; + final fcmOptions = FcmPlatformOptions( + channelId: switch (json['fcmOptions']) { + {'channelId': final String channelId} => channelId, + _ => null, + }, + messageId: switch (json['fcmOptions']) { + {'messageId': final String messageId} => messageId, + _ => null, + }, + ); + return PushNotificationMessage( + title: title, + body: body, + imageUrl: imageUrl, + deeplinkUrl: deeplinkUrl, + goToUrl: goToUrl, + fcmOptions: fcmOptions, + data: data, ); - } } - return PushNotificationMessage( - title: title, - body: body, - imageUrl: imageUrl, - deeplinkUrl: deeplinkUrl, - goToUrl: goToUrl, - apnsOptions: apnsOptions, - fcmOptions: fcmOptions, - data: data, - ); } final String? title; @@ -81,7 +98,7 @@ class PushNotificationMessage final String? goToUrl; final FcmPlatformOptions? fcmOptions; final ApnsPlatformOptions? apnsOptions; - final Map data; + final Map data; @override String get runtimeTypeName => 'PushNotificationMessage'; diff --git a/packages/notifications/push/amplify_push_notifications/test/push_notification_message_test.dart b/packages/notifications/push/amplify_push_notifications/test/push_notification_message_test.dart index 3c435053b6..e5bd66c336 100644 --- a/packages/notifications/push/amplify_push_notifications/test/push_notification_message_test.dart +++ b/packages/notifications/push/amplify_push_notifications/test/push_notification_message_test.dart @@ -20,6 +20,10 @@ void main() { 'PINPOINT.NOTIFICATION', ); + final parsedSimpleiOSMessage = + PushNotificationMessage.fromJson(simpleAlertiOSMessage); + expect(parsedSimpleiOSMessage.title, 'Hello, world'); + final parsediOSMessage = PushNotificationMessage.fromJson(standardiOSMessage); expect(parsediOSMessage.title, 'TITTLE'); diff --git a/packages/notifications/push/amplify_push_notifications/test/test_data/fake_notification_messges.dart b/packages/notifications/push/amplify_push_notifications/test/test_data/fake_notification_messges.dart index 29cc89b050..d8a422dcc7 100644 --- a/packages/notifications/push/amplify_push_notifications/test/test_data/fake_notification_messges.dart +++ b/packages/notifications/push/amplify_push_notifications/test/test_data/fake_notification_messges.dart @@ -60,6 +60,12 @@ const standardiOSMessage = { }, }; +const simpleAlertiOSMessage = { + 'aps': { + 'alert': 'Hello, world', + }, +}; + const imageUrliOSMessage = { 'data': { 'media-url': 'TEST_URL',