expo-notifications 0.28.14 → 0.28.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.28.15 — 2024-08-05
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [Android] Eliminate unsupported types when processing notification intents from onCreate/onNewIntent. ([#30750](https://github.com/expo/expo/pull/30750) by [@douglowder](https://github.com/douglowder))
18
+
13
19
  ## 0.28.14 — 2024-07-30
14
20
 
15
21
  ### 🐛 Bug fixes
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'host.exp.exponent'
4
- version = '0.28.14'
4
+ version = '0.28.15'
5
5
 
6
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
7
  apply from: expoModulesCorePlugin
@@ -14,7 +14,7 @@ android {
14
14
  namespace "expo.modules.notifications"
15
15
  defaultConfig {
16
16
  versionCode 21
17
- versionName '0.28.14'
17
+ versionName '0.28.15'
18
18
  }
19
19
 
20
20
  buildFeatures {
@@ -3,8 +3,13 @@ package expo.modules.notifications
3
3
  import android.os.Bundle
4
4
  import android.os.Handler
5
5
  import android.os.ResultReceiver
6
+ import expo.modules.kotlin.types.JSTypeConverter
7
+ import org.json.JSONArray
8
+ import org.json.JSONException
9
+ import org.json.JSONObject
6
10
 
7
11
  typealias ResultReceiverBody = (resultCode: Int, resultData: Bundle?) -> Unit
12
+ typealias BundleConversionTester = (bundle: Bundle) -> Boolean
8
13
 
9
14
  internal fun createDefaultResultReceiver(
10
15
  handler: Handler?,
@@ -17,3 +22,87 @@ internal fun createDefaultResultReceiver(
17
22
  }
18
23
  }
19
24
  }
25
+
26
+ /**
27
+ * Given an input bundle, creates a new bundle with non-convertible objects removed
28
+ */
29
+ internal fun filteredBundleForJSTypeConverter(bundle: Bundle): Bundle {
30
+ return filteredBundleForJSTypeConverter(bundle, isBundleConvertibleToJSValue)
31
+ }
32
+
33
+ internal fun filteredBundleForJSTypeConverter(bundle: Bundle, testBundle: BundleConversionTester): Bundle {
34
+ return when (testBundle(bundle)) {
35
+ true -> bundle
36
+ else -> {
37
+ // Store keys whose values are convertible
38
+ val goodKeys: MutableSet<String> = mutableSetOf()
39
+ // Do first pass to filter any values that are bundles
40
+ bundle.keySet().forEach { key: String ->
41
+ val value = bundle[key]
42
+ if (value is Bundle) {
43
+ bundle.putBundle(key, filteredBundleForJSTypeConverter(value, testBundle))
44
+ goodKeys.add(key)
45
+ }
46
+ }
47
+ // Second pass: create a bundle with just the value for that key, and see if it converts
48
+ // There is no generic put() method for bundles, so we putAll() and then remove values
49
+ // other than the one we are testing
50
+ bundle.keySet().forEach { key: String ->
51
+ if (!goodKeys.contains(key)) {
52
+ val test = Bundle()
53
+ test.putAll(bundle)
54
+ bundle.keySet().forEach { otherKey: String ->
55
+ if (!otherKey.equals(key)) {
56
+ test.remove(otherKey)
57
+ }
58
+ }
59
+ if (testBundle(test)) {
60
+ goodKeys.add(key)
61
+ }
62
+ }
63
+ }
64
+ // Now create a new bundle, remove keys that are not good, and return
65
+ val result = Bundle()
66
+ result.putAll(bundle)
67
+ bundle.keySet().forEach { key: String ->
68
+ if (!goodKeys.contains(key)) {
69
+ result.remove(key)
70
+ }
71
+ }
72
+ result
73
+ }
74
+ }
75
+ }
76
+
77
+ internal val isBundleConvertibleToJSValue: BundleConversionTester = { bundle: Bundle ->
78
+ try {
79
+ JSTypeConverter.convertToJSValue(bundle)
80
+ true
81
+ } catch (e: Throwable) {
82
+ false
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Returns true if the argument is a valid JSON string, false otherwise
88
+ */
89
+ internal fun isValidJSONString(test: Any?): Boolean {
90
+ when (test is String) {
91
+ true -> {
92
+ try {
93
+ JSONObject(test as String)
94
+ return true
95
+ } catch (objectEx: JSONException) {
96
+ try {
97
+ JSONArray(test as String)
98
+ return true
99
+ } catch (arrayEx: JSONException) {
100
+ return false
101
+ }
102
+ }
103
+ }
104
+ else -> {
105
+ return false
106
+ }
107
+ }
108
+ }
@@ -1,5 +1,8 @@
1
1
  package expo.modules.notifications.notifications;
2
2
 
3
+ import static expo.modules.notifications.UtilsKt.filteredBundleForJSTypeConverter;
4
+ import static expo.modules.notifications.UtilsKt.isValidJSONString;
5
+
3
6
  import android.os.Build;
4
7
  import android.os.Bundle;
5
8
 
@@ -9,7 +12,6 @@ import com.google.firebase.messaging.RemoteMessage;
9
12
 
10
13
  import org.jetbrains.annotations.NotNull;
11
14
  import org.json.JSONArray;
12
- import org.json.JSONException;
13
15
  import org.json.JSONObject;
14
16
  import expo.modules.core.arguments.MapArguments;
15
17
 
@@ -58,8 +60,7 @@ public class NotificationSerializer {
58
60
  serializedRequest.putBundle("trigger", toBundle(request.getTrigger()));
59
61
  Bundle content = toBundle(request.getContent());
60
62
  Bundle existingContentData = content.getBundle("data");
61
- if (existingContentData == null) {
62
- FirebaseNotificationTrigger trigger = (FirebaseNotificationTrigger) request.getTrigger();
63
+ if (existingContentData == null && request.getTrigger() instanceof FirebaseNotificationTrigger trigger) {
63
64
  RemoteMessage message = trigger.getRemoteMessage();
64
65
  RemoteMessage.Notification notification = message.getNotification();
65
66
  Map<String, String> data = message.getData();
@@ -226,17 +227,17 @@ public class NotificationSerializer {
226
227
  Bundle serializedContent = new Bundle();
227
228
  serializedContent.putString("title", extras.getString("title"));
228
229
  String body = extras.getString("body");
229
- String projectId = extras.getString("projectId");
230
- if (projectId != null && isValidJSONString(body) ) {
231
- // If projectId is set in the bundle, and the body is a JSON string,
230
+ if (isValidJSONString(body) ) {
231
+ // If the body is a JSON string,
232
232
  // the notification was sent by the Expo notification service,
233
233
  // so we do the expected remapping of fields
234
234
  serializedContent.putString("dataString", body);
235
235
  serializedContent.putString("body", extras.getString("message"));
236
236
  } else {
237
237
  // The notification came directly from Firebase or some other service,
238
- // so we copy the data as is from the extras bundle
239
- serializedContent.putBundle("data", extras);
238
+ // so we copy the data as is from the extras bundle, after
239
+ // ensuring it can be converted for emitting to JS
240
+ serializedContent.putBundle("data", filteredBundleForJSTypeConverter(extras));
240
241
  }
241
242
 
242
243
  Bundle serializedTrigger = new Bundle();
@@ -259,17 +260,4 @@ public class NotificationSerializer {
259
260
  return serializedResponse;
260
261
  }
261
262
 
262
- public static boolean isValidJSONString(String test) {
263
- try {
264
- new JSONObject(test);
265
- } catch (JSONException objectEx) {
266
- try {
267
- new JSONArray(test);
268
- } catch (JSONException arrayEx) {
269
- return false;
270
- }
271
- }
272
- return true;
273
- }
274
-
275
263
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-notifications",
3
- "version": "0.28.14",
3
+ "version": "0.28.15",
4
4
  "description": "Notifications module",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -55,5 +55,5 @@
55
55
  "peerDependencies": {
56
56
  "expo": "*"
57
57
  },
58
- "gitHead": "10eaf729822bf46ab821a000eb961cf8df40b35b"
58
+ "gitHead": "760c0c1a3bebcedc19836db8bc98c737f0db8c8d"
59
59
  }