@react-native-firebase/messaging 23.8.0 → 23.8.1
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 +1193 -0
- package/RNFBMessaging.podspec +50 -0
- package/android/.editorconfig +10 -0
- package/android/build.gradle +149 -0
- package/android/lint.xml +5 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +43 -0
- package/android/src/main/java/io/invertase/firebase/messaging/JsonConvert.java +127 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingHeadlessService.java +30 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingModule.java +332 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingPackage.java +41 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingReceiver.java +66 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingSerializer.java +225 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingService.java +37 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStore.java +15 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStoreHelper.java +23 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStoreImpl.java +97 -0
- package/android/src/main/res/values/colors.xml +143 -0
- package/app.plugin.js +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/commonjs/lib/namespaced.d.ts +1 -1
- package/dist/typescript/commonjs/lib/version.d.ts +1 -1
- package/dist/typescript/module/lib/namespaced.d.ts +1 -1
- package/dist/typescript/module/lib/version.d.ts +1 -1
- package/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h +54 -0
- package/ios/RNFBMessaging/RNFBMessaging+AppDelegate.m +251 -0
- package/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.h +31 -0
- package/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.m +70 -0
- package/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.h +29 -0
- package/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m +173 -0
- package/ios/RNFBMessaging/RNFBMessaging+UNUserNotificationCenter.h +37 -0
- package/ios/RNFBMessaging/RNFBMessaging+UNUserNotificationCenter.m +185 -0
- package/ios/RNFBMessaging/RNFBMessagingModule.h +26 -0
- package/ios/RNFBMessaging/RNFBMessagingModule.m +431 -0
- package/ios/RNFBMessaging/RNFBMessagingSerializer.h +32 -0
- package/ios/RNFBMessaging/RNFBMessagingSerializer.m +235 -0
- package/ios/RNFBMessaging.xcodeproj/project.pbxproj +384 -0
- package/ios/RNFBMessaging.xcodeproj/xcshareddata/IDETemplateMacros.plist +24 -0
- package/lib/version.ts +1 -1
- package/package.json +5 -15
- package/plugin/build/android/index.d.ts +2 -0
- package/plugin/build/android/index.js +5 -0
- package/plugin/build/android/setupFirebaseNotifationIcon.d.ts +8 -0
- package/plugin/build/android/setupFirebaseNotifationIcon.js +62 -0
- package/plugin/build/index.d.ts +3 -0
- package/plugin/build/index.js +16 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
package io.invertase.firebase.messaging;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import android.app.Activity;
|
|
21
|
+
import android.content.Intent;
|
|
22
|
+
import android.util.Log;
|
|
23
|
+
import androidx.core.app.NotificationManagerCompat;
|
|
24
|
+
import com.facebook.react.bridge.ActivityEventListener;
|
|
25
|
+
import com.facebook.react.bridge.Promise;
|
|
26
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
27
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
28
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
29
|
+
import com.facebook.react.bridge.WritableMap;
|
|
30
|
+
import com.facebook.react.bridge.WritableNativeMap;
|
|
31
|
+
import com.google.android.gms.tasks.Tasks;
|
|
32
|
+
import com.google.firebase.FirebaseApp;
|
|
33
|
+
import com.google.firebase.messaging.FirebaseMessaging;
|
|
34
|
+
import com.google.firebase.messaging.RemoteMessage;
|
|
35
|
+
import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter;
|
|
36
|
+
import io.invertase.firebase.common.ReactNativeFirebaseModule;
|
|
37
|
+
import java.util.HashMap;
|
|
38
|
+
import java.util.Map;
|
|
39
|
+
|
|
40
|
+
public class ReactNativeFirebaseMessagingModule extends ReactNativeFirebaseModule
|
|
41
|
+
implements ActivityEventListener {
|
|
42
|
+
private static final String TAG = "Messaging";
|
|
43
|
+
ReadableMap initialNotification = null;
|
|
44
|
+
private HashMap<String, Boolean> initialNotificationMap = new HashMap<>();
|
|
45
|
+
|
|
46
|
+
ReactNativeFirebaseMessagingModule(ReactApplicationContext reactContext) {
|
|
47
|
+
super(reactContext, TAG);
|
|
48
|
+
reactContext.addActivityEventListener(this);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private WritableMap popRemoteMessageMapFromMessagingStore(String messageId) {
|
|
52
|
+
ReactNativeFirebaseMessagingStore messagingStore =
|
|
53
|
+
ReactNativeFirebaseMessagingStoreHelper.getInstance().getMessagingStore();
|
|
54
|
+
WritableMap remoteMessageMap = messagingStore.getFirebaseMessageMap(messageId);
|
|
55
|
+
messagingStore.clearFirebaseMessage(messageId);
|
|
56
|
+
return remoteMessageMap;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@ReactMethod
|
|
60
|
+
public void getInitialNotification(Promise promise) {
|
|
61
|
+
if (initialNotification != null) {
|
|
62
|
+
promise.resolve(initialNotification);
|
|
63
|
+
initialNotification = null;
|
|
64
|
+
return;
|
|
65
|
+
} else {
|
|
66
|
+
Activity activity = getCurrentActivity();
|
|
67
|
+
|
|
68
|
+
if (activity != null) {
|
|
69
|
+
Intent intent = activity.getIntent();
|
|
70
|
+
|
|
71
|
+
if (intent != null && intent.getExtras() != null) {
|
|
72
|
+
// messageId can be either one...
|
|
73
|
+
String messageId = intent.getExtras().getString("google.message_id");
|
|
74
|
+
if (messageId == null) messageId = intent.getExtras().getString("message_id");
|
|
75
|
+
|
|
76
|
+
// only handle non-consumed initial notifications
|
|
77
|
+
if (messageId != null && initialNotificationMap.get(messageId) == null) {
|
|
78
|
+
WritableMap remoteMessageMap;
|
|
79
|
+
RemoteMessage remoteMessage =
|
|
80
|
+
ReactNativeFirebaseMessagingReceiver.notifications.get(messageId);
|
|
81
|
+
if (remoteMessage == null) {
|
|
82
|
+
remoteMessageMap = popRemoteMessageMapFromMessagingStore(messageId);
|
|
83
|
+
} else {
|
|
84
|
+
remoteMessageMap =
|
|
85
|
+
ReactNativeFirebaseMessagingSerializer.remoteMessageToWritableMap(remoteMessage);
|
|
86
|
+
}
|
|
87
|
+
if (remoteMessageMap != null) {
|
|
88
|
+
promise.resolve(remoteMessageMap);
|
|
89
|
+
initialNotificationMap.put(messageId, true);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
Log.w(
|
|
96
|
+
TAG,
|
|
97
|
+
"Attempt to call getInitialNotification failed. The current activity is not ready, try"
|
|
98
|
+
+ " calling the method later in the React lifecycle.");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
promise.resolve(null);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@ReactMethod
|
|
106
|
+
public void setAutoInitEnabled(Boolean enabled, Promise promise) {
|
|
107
|
+
Tasks.call(
|
|
108
|
+
getExecutor(),
|
|
109
|
+
() -> {
|
|
110
|
+
FirebaseMessaging.getInstance().setAutoInitEnabled(enabled);
|
|
111
|
+
return null;
|
|
112
|
+
})
|
|
113
|
+
.addOnCompleteListener(
|
|
114
|
+
task -> {
|
|
115
|
+
if (task.isSuccessful()) {
|
|
116
|
+
promise.resolve(FirebaseMessaging.getInstance().isAutoInitEnabled());
|
|
117
|
+
} else {
|
|
118
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@ReactMethod
|
|
124
|
+
public void isNotificationDelegationEnabled(Promise promise) {
|
|
125
|
+
Tasks.call(
|
|
126
|
+
getExecutor(),
|
|
127
|
+
() -> {
|
|
128
|
+
FirebaseMessaging.getInstance().isNotificationDelegationEnabled();
|
|
129
|
+
return null;
|
|
130
|
+
})
|
|
131
|
+
.addOnCompleteListener(
|
|
132
|
+
task -> {
|
|
133
|
+
if (task.isSuccessful()) {
|
|
134
|
+
promise.resolve(task.getResult());
|
|
135
|
+
} else {
|
|
136
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@ReactMethod
|
|
142
|
+
public void setNotificationDelegationEnabled(Boolean enabled, Promise promise) {
|
|
143
|
+
Tasks.call(
|
|
144
|
+
getExecutor(),
|
|
145
|
+
() -> {
|
|
146
|
+
FirebaseMessaging.getInstance().setNotificationDelegationEnabled(enabled);
|
|
147
|
+
return null;
|
|
148
|
+
})
|
|
149
|
+
.addOnCompleteListener(
|
|
150
|
+
task -> {
|
|
151
|
+
if (task.isSuccessful()) {
|
|
152
|
+
promise.resolve(FirebaseMessaging.getInstance().isNotificationDelegationEnabled());
|
|
153
|
+
} else {
|
|
154
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@ReactMethod
|
|
160
|
+
public void getToken(String appName, String senderId, Promise promise) {
|
|
161
|
+
FirebaseMessaging messagingInstance =
|
|
162
|
+
FirebaseApp.getInstance(appName).get(FirebaseMessaging.class);
|
|
163
|
+
Tasks.call(getExecutor(), () -> Tasks.await(messagingInstance.getToken()))
|
|
164
|
+
.addOnCompleteListener(
|
|
165
|
+
task -> {
|
|
166
|
+
if (task.isSuccessful()) {
|
|
167
|
+
promise.resolve(task.getResult());
|
|
168
|
+
} else {
|
|
169
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@ReactMethod
|
|
175
|
+
public void deleteToken(String appName, String senderId, Promise promise) {
|
|
176
|
+
FirebaseMessaging messagingInstance =
|
|
177
|
+
FirebaseApp.getInstance(appName).get(FirebaseMessaging.class);
|
|
178
|
+
Tasks.call(
|
|
179
|
+
getExecutor(),
|
|
180
|
+
() -> {
|
|
181
|
+
Tasks.await(messagingInstance.deleteToken());
|
|
182
|
+
return null;
|
|
183
|
+
})
|
|
184
|
+
.addOnCompleteListener(
|
|
185
|
+
task -> {
|
|
186
|
+
if (task.isSuccessful()) {
|
|
187
|
+
promise.resolve(task.getResult());
|
|
188
|
+
} else {
|
|
189
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
@ReactMethod
|
|
195
|
+
public void hasPermission(Promise promise) {
|
|
196
|
+
Tasks.call(
|
|
197
|
+
getExecutor(),
|
|
198
|
+
() ->
|
|
199
|
+
NotificationManagerCompat.from(getReactApplicationContext())
|
|
200
|
+
.areNotificationsEnabled())
|
|
201
|
+
.addOnCompleteListener(
|
|
202
|
+
task -> {
|
|
203
|
+
if (task.isSuccessful()) {
|
|
204
|
+
promise.resolve(task.getResult() ? 1 : 0);
|
|
205
|
+
} else {
|
|
206
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@ReactMethod
|
|
212
|
+
public void sendMessage(ReadableMap remoteMessageMap, Promise promise) {
|
|
213
|
+
Tasks.call(
|
|
214
|
+
getExecutor(),
|
|
215
|
+
() -> {
|
|
216
|
+
FirebaseMessaging.getInstance()
|
|
217
|
+
.send(
|
|
218
|
+
ReactNativeFirebaseMessagingSerializer.remoteMessageFromReadableMap(
|
|
219
|
+
remoteMessageMap));
|
|
220
|
+
return null;
|
|
221
|
+
})
|
|
222
|
+
.addOnCompleteListener(
|
|
223
|
+
task -> {
|
|
224
|
+
if (task.isSuccessful()) {
|
|
225
|
+
promise.resolve(task.getResult());
|
|
226
|
+
} else {
|
|
227
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@ReactMethod
|
|
233
|
+
public void subscribeToTopic(String topic, Promise promise) {
|
|
234
|
+
FirebaseMessaging.getInstance()
|
|
235
|
+
.subscribeToTopic(topic)
|
|
236
|
+
.addOnCompleteListener(
|
|
237
|
+
task -> {
|
|
238
|
+
if (task.isSuccessful()) {
|
|
239
|
+
promise.resolve(task.getResult());
|
|
240
|
+
} else {
|
|
241
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@ReactMethod
|
|
247
|
+
public void unsubscribeFromTopic(String topic, Promise promise) {
|
|
248
|
+
FirebaseMessaging.getInstance()
|
|
249
|
+
.unsubscribeFromTopic(topic)
|
|
250
|
+
.addOnCompleteListener(
|
|
251
|
+
task -> {
|
|
252
|
+
if (task.isSuccessful()) {
|
|
253
|
+
promise.resolve(task.getResult());
|
|
254
|
+
} else {
|
|
255
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@ReactMethod
|
|
261
|
+
public void setDeliveryMetricsExportToBigQuery(Boolean enabled, Promise promise) {
|
|
262
|
+
Tasks.call(
|
|
263
|
+
getExecutor(),
|
|
264
|
+
() -> {
|
|
265
|
+
FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(enabled);
|
|
266
|
+
return null;
|
|
267
|
+
})
|
|
268
|
+
.addOnCompleteListener(
|
|
269
|
+
task -> {
|
|
270
|
+
if (task.isSuccessful()) {
|
|
271
|
+
promise.resolve(
|
|
272
|
+
FirebaseMessaging.getInstance().deliveryMetricsExportToBigQueryEnabled());
|
|
273
|
+
} else {
|
|
274
|
+
rejectPromiseWithExceptionMap(promise, task.getException());
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@Override
|
|
280
|
+
public Map<String, Object> getConstants() {
|
|
281
|
+
final Map<String, Object> constants = new HashMap<>();
|
|
282
|
+
constants.put("isAutoInitEnabled", FirebaseMessaging.getInstance().isAutoInitEnabled());
|
|
283
|
+
constants.put(
|
|
284
|
+
"isDeliveryMetricsExportToBigQueryEnabled",
|
|
285
|
+
FirebaseMessaging.getInstance().deliveryMetricsExportToBigQueryEnabled());
|
|
286
|
+
constants.put(
|
|
287
|
+
"isNotificationDelegationEnabled",
|
|
288
|
+
FirebaseMessaging.getInstance().isNotificationDelegationEnabled());
|
|
289
|
+
return constants;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
@Override
|
|
293
|
+
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
|
294
|
+
// noop
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
@Override
|
|
298
|
+
public void onNewIntent(Intent intent) {
|
|
299
|
+
if (intent != null && intent.getExtras() != null) {
|
|
300
|
+
String messageId = intent.getExtras().getString("google.message_id");
|
|
301
|
+
if (messageId == null) messageId = intent.getExtras().getString("message_id");
|
|
302
|
+
|
|
303
|
+
if (messageId != null) {
|
|
304
|
+
RemoteMessage remoteMessage =
|
|
305
|
+
ReactNativeFirebaseMessagingReceiver.notifications.get(messageId);
|
|
306
|
+
WritableMap remoteMessageMap;
|
|
307
|
+
|
|
308
|
+
if (remoteMessage == null) {
|
|
309
|
+
remoteMessageMap = popRemoteMessageMapFromMessagingStore(messageId);
|
|
310
|
+
} else {
|
|
311
|
+
remoteMessageMap =
|
|
312
|
+
ReactNativeFirebaseMessagingSerializer.remoteMessageToWritableMap(remoteMessage);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (remoteMessageMap != null) {
|
|
316
|
+
// WritableNativeMap not be consumed twice. But it is resolved in future and in event
|
|
317
|
+
// below. Make a copy - issue #5231
|
|
318
|
+
WritableNativeMap newInitialNotification = new WritableNativeMap();
|
|
319
|
+
newInitialNotification.merge(remoteMessageMap);
|
|
320
|
+
initialNotification = newInitialNotification;
|
|
321
|
+
ReactNativeFirebaseMessagingReceiver.notifications.remove(messageId);
|
|
322
|
+
|
|
323
|
+
ReactNativeFirebaseEventEmitter emitter =
|
|
324
|
+
ReactNativeFirebaseEventEmitter.getSharedInstance();
|
|
325
|
+
emitter.sendEvent(
|
|
326
|
+
ReactNativeFirebaseMessagingSerializer.remoteMessageMapToEvent(
|
|
327
|
+
remoteMessageMap, true));
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package io.invertase.firebase.messaging;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import com.facebook.react.ReactPackage;
|
|
21
|
+
import com.facebook.react.bridge.NativeModule;
|
|
22
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
23
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
24
|
+
import java.util.ArrayList;
|
|
25
|
+
import java.util.Collections;
|
|
26
|
+
import java.util.List;
|
|
27
|
+
|
|
28
|
+
@SuppressWarnings("unused")
|
|
29
|
+
public class ReactNativeFirebaseMessagingPackage implements ReactPackage {
|
|
30
|
+
@Override
|
|
31
|
+
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
32
|
+
List<NativeModule> modules = new ArrayList<>();
|
|
33
|
+
modules.add(new ReactNativeFirebaseMessagingModule(reactContext));
|
|
34
|
+
return modules;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Override
|
|
38
|
+
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
39
|
+
return Collections.emptyList();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
package io.invertase.firebase.messaging;
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver;
|
|
4
|
+
import android.content.ComponentName;
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import android.content.Intent;
|
|
7
|
+
import android.util.Log;
|
|
8
|
+
import com.facebook.react.HeadlessJsTaskService;
|
|
9
|
+
import com.google.firebase.messaging.RemoteMessage;
|
|
10
|
+
import io.invertase.firebase.app.ReactNativeFirebaseApp;
|
|
11
|
+
import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter;
|
|
12
|
+
import io.invertase.firebase.common.SharedUtils;
|
|
13
|
+
import java.util.HashMap;
|
|
14
|
+
|
|
15
|
+
public class ReactNativeFirebaseMessagingReceiver extends BroadcastReceiver {
|
|
16
|
+
private static final String TAG = "RNFirebaseMsgReceiver";
|
|
17
|
+
static HashMap<String, RemoteMessage> notifications = new HashMap<>();
|
|
18
|
+
|
|
19
|
+
@Override
|
|
20
|
+
public void onReceive(Context context, Intent intent) {
|
|
21
|
+
Log.d(TAG, "broadcast received for message");
|
|
22
|
+
if (ReactNativeFirebaseApp.getApplicationContext() == null) {
|
|
23
|
+
ReactNativeFirebaseApp.setApplicationContext(context.getApplicationContext());
|
|
24
|
+
}
|
|
25
|
+
if (intent.getExtras() == null) {
|
|
26
|
+
Log.e(TAG, "broadcast intent received with no extras");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
RemoteMessage remoteMessage = new RemoteMessage(intent.getExtras());
|
|
30
|
+
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
|
|
31
|
+
|
|
32
|
+
// Add a RemoteMessage if the message contains a notification payload
|
|
33
|
+
if (remoteMessage.getNotification() != null) {
|
|
34
|
+
notifications.put(remoteMessage.getMessageId(), remoteMessage);
|
|
35
|
+
ReactNativeFirebaseMessagingStoreHelper.getInstance()
|
|
36
|
+
.getMessagingStore()
|
|
37
|
+
.storeFirebaseMessage(remoteMessage);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// |-> ---------------------
|
|
41
|
+
// App in Foreground
|
|
42
|
+
// ------------------------
|
|
43
|
+
if (SharedUtils.isAppInForeground(context)) {
|
|
44
|
+
emitter.sendEvent(
|
|
45
|
+
ReactNativeFirebaseMessagingSerializer.remoteMessageToEvent(remoteMessage, false));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// |-> ---------------------
|
|
50
|
+
// App in Background/Quit
|
|
51
|
+
// ------------------------
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
Intent backgroundIntent =
|
|
55
|
+
new Intent(context, ReactNativeFirebaseMessagingHeadlessService.class);
|
|
56
|
+
backgroundIntent.putExtra("message", remoteMessage);
|
|
57
|
+
ComponentName name = context.startService(backgroundIntent);
|
|
58
|
+
if (name != null) {
|
|
59
|
+
HeadlessJsTaskService.acquireWakeLockNow(context);
|
|
60
|
+
}
|
|
61
|
+
} catch (IllegalStateException ex) {
|
|
62
|
+
// By default, data only messages are "default" priority and cannot trigger Headless tasks
|
|
63
|
+
Log.e(TAG, "Background messages only work if the message priority is set to 'high'", ex);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
package io.invertase.firebase.messaging;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments;
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
5
|
+
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
6
|
+
import com.facebook.react.bridge.WritableMap;
|
|
7
|
+
import com.google.firebase.messaging.RemoteMessage;
|
|
8
|
+
import io.invertase.firebase.common.ReactNativeFirebaseEvent;
|
|
9
|
+
import io.invertase.firebase.common.SharedUtils;
|
|
10
|
+
import java.util.Map;
|
|
11
|
+
import java.util.Set;
|
|
12
|
+
|
|
13
|
+
public class ReactNativeFirebaseMessagingSerializer {
|
|
14
|
+
private static final String KEY_TOKEN = "token";
|
|
15
|
+
private static final String KEY_COLLAPSE_KEY = "collapseKey";
|
|
16
|
+
private static final String KEY_DATA = "data";
|
|
17
|
+
private static final String KEY_FROM = "from";
|
|
18
|
+
private static final String KEY_MESSAGE_ID = "messageId";
|
|
19
|
+
private static final String KEY_MESSAGE_TYPE = "messageType";
|
|
20
|
+
private static final String KEY_SENT_TIME = "sentTime";
|
|
21
|
+
private static final String KEY_ERROR = "error";
|
|
22
|
+
private static final String KEY_TO = "to";
|
|
23
|
+
private static final String KEY_TTL = "ttl";
|
|
24
|
+
private static final String KEY_PRIORITY = "priority";
|
|
25
|
+
private static final String KEY_ORIGINAL_PRIORITY = "originalPriority";
|
|
26
|
+
private static final String EVENT_MESSAGE_SENT = "messaging_message_sent";
|
|
27
|
+
private static final String EVENT_MESSAGES_DELETED = "messaging_message_deleted";
|
|
28
|
+
private static final String EVENT_MESSAGE_RECEIVED = "messaging_message_received";
|
|
29
|
+
private static final String EVENT_NOTIFICATION_OPENED = "messaging_notification_opened";
|
|
30
|
+
private static final String EVENT_MESSAGE_SEND_ERROR = "messaging_message_send_error";
|
|
31
|
+
private static final String EVENT_NEW_TOKEN = "messaging_token_refresh";
|
|
32
|
+
|
|
33
|
+
public static ReactNativeFirebaseEvent messagesDeletedToEvent() {
|
|
34
|
+
return new ReactNativeFirebaseEvent(EVENT_MESSAGES_DELETED, Arguments.createMap());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public static ReactNativeFirebaseEvent messageSentToEvent(String messageId) {
|
|
38
|
+
WritableMap eventBody = Arguments.createMap();
|
|
39
|
+
eventBody.putString(KEY_MESSAGE_ID, messageId);
|
|
40
|
+
return new ReactNativeFirebaseEvent(EVENT_MESSAGE_SENT, eventBody);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public static ReactNativeFirebaseEvent messageSendErrorToEvent(
|
|
44
|
+
String messageId, Exception sendError) {
|
|
45
|
+
WritableMap eventBody = Arguments.createMap();
|
|
46
|
+
eventBody.putString(KEY_MESSAGE_ID, messageId);
|
|
47
|
+
eventBody.putMap(KEY_ERROR, SharedUtils.getExceptionMap(sendError));
|
|
48
|
+
return new ReactNativeFirebaseEvent(EVENT_MESSAGE_SEND_ERROR, eventBody);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public static ReactNativeFirebaseEvent remoteMessageToEvent(
|
|
52
|
+
RemoteMessage remoteMessage, Boolean openEvent) {
|
|
53
|
+
return new ReactNativeFirebaseEvent(
|
|
54
|
+
openEvent ? EVENT_NOTIFICATION_OPENED : EVENT_MESSAGE_RECEIVED,
|
|
55
|
+
remoteMessageToWritableMap(remoteMessage));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public static ReactNativeFirebaseEvent remoteMessageMapToEvent(
|
|
59
|
+
WritableMap remoteMessageMap, Boolean openEvent) {
|
|
60
|
+
return new ReactNativeFirebaseEvent(
|
|
61
|
+
openEvent ? EVENT_NOTIFICATION_OPENED : EVENT_MESSAGE_RECEIVED, remoteMessageMap);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static ReactNativeFirebaseEvent newTokenToTokenEvent(String newToken) {
|
|
65
|
+
WritableMap eventBody = Arguments.createMap();
|
|
66
|
+
eventBody.putString(KEY_TOKEN, newToken);
|
|
67
|
+
return new ReactNativeFirebaseEvent(EVENT_NEW_TOKEN, eventBody);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static WritableMap remoteMessageToWritableMap(RemoteMessage remoteMessage) {
|
|
71
|
+
WritableMap messageMap = Arguments.createMap();
|
|
72
|
+
WritableMap dataMap = Arguments.createMap();
|
|
73
|
+
|
|
74
|
+
if (remoteMessage.getCollapseKey() != null) {
|
|
75
|
+
messageMap.putString(KEY_COLLAPSE_KEY, remoteMessage.getCollapseKey());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (remoteMessage.getFrom() != null) {
|
|
79
|
+
messageMap.putString(KEY_FROM, remoteMessage.getFrom());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (remoteMessage.getTo() != null) {
|
|
83
|
+
messageMap.putString(KEY_TO, remoteMessage.getTo());
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (remoteMessage.getMessageId() != null) {
|
|
87
|
+
messageMap.putString(KEY_MESSAGE_ID, remoteMessage.getMessageId());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (remoteMessage.getMessageType() != null) {
|
|
91
|
+
messageMap.putString(KEY_MESSAGE_TYPE, remoteMessage.getMessageType());
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (remoteMessage.getData().size() > 0) {
|
|
95
|
+
Set<Map.Entry<String, String>> entries = remoteMessage.getData().entrySet();
|
|
96
|
+
for (Map.Entry<String, String> entry : entries) {
|
|
97
|
+
dataMap.putString(entry.getKey(), entry.getValue());
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
messageMap.putMap(KEY_DATA, dataMap);
|
|
102
|
+
messageMap.putDouble(KEY_TTL, remoteMessage.getTtl());
|
|
103
|
+
messageMap.putDouble(KEY_SENT_TIME, remoteMessage.getSentTime());
|
|
104
|
+
messageMap.putInt(KEY_PRIORITY, remoteMessage.getPriority());
|
|
105
|
+
messageMap.putInt(KEY_ORIGINAL_PRIORITY, remoteMessage.getOriginalPriority());
|
|
106
|
+
|
|
107
|
+
if (remoteMessage.getNotification() != null) {
|
|
108
|
+
messageMap.putMap(
|
|
109
|
+
"notification", remoteMessageNotificationToWritableMap(remoteMessage.getNotification()));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return messageMap;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static WritableMap remoteMessageNotificationToWritableMap(
|
|
116
|
+
RemoteMessage.Notification notification) {
|
|
117
|
+
WritableMap notificationMap = Arguments.createMap();
|
|
118
|
+
WritableMap androidNotificationMap = Arguments.createMap();
|
|
119
|
+
|
|
120
|
+
if (notification.getTitle() != null) {
|
|
121
|
+
notificationMap.putString("title", notification.getTitle());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (notification.getTitleLocalizationKey() != null) {
|
|
125
|
+
notificationMap.putString("titleLocKey", notification.getTitleLocalizationKey());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (notification.getTitleLocalizationArgs() != null) {
|
|
129
|
+
notificationMap.putArray(
|
|
130
|
+
"titleLocArgs", Arguments.fromJavaArgs(notification.getTitleLocalizationArgs()));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (notification.getBody() != null) {
|
|
134
|
+
notificationMap.putString("body", notification.getBody());
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (notification.getBodyLocalizationKey() != null) {
|
|
138
|
+
notificationMap.putString("bodyLocKey", notification.getBodyLocalizationKey());
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (notification.getBodyLocalizationArgs() != null) {
|
|
142
|
+
notificationMap.putArray(
|
|
143
|
+
"bodyLocArgs", Arguments.fromJavaArgs(notification.getBodyLocalizationArgs()));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (notification.getChannelId() != null) {
|
|
147
|
+
androidNotificationMap.putString("channelId", notification.getChannelId());
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (notification.getClickAction() != null) {
|
|
151
|
+
androidNotificationMap.putString("clickAction", notification.getClickAction());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (notification.getColor() != null) {
|
|
155
|
+
androidNotificationMap.putString("color", notification.getColor());
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (notification.getIcon() != null) {
|
|
159
|
+
androidNotificationMap.putString("smallIcon", notification.getIcon());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (notification.getImageUrl() != null) {
|
|
163
|
+
androidNotificationMap.putString("imageUrl", notification.getImageUrl().toString());
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (notification.getLink() != null) {
|
|
167
|
+
androidNotificationMap.putString("link", notification.getLink().toString());
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (notification.getNotificationCount() != null) {
|
|
171
|
+
androidNotificationMap.putInt("count", notification.getNotificationCount());
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (notification.getNotificationPriority() != null) {
|
|
175
|
+
androidNotificationMap.putInt("priority", notification.getNotificationPriority());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (notification.getSound() != null) {
|
|
179
|
+
androidNotificationMap.putString("sound", notification.getSound());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (notification.getTicker() != null) {
|
|
183
|
+
androidNotificationMap.putString("ticker", notification.getTicker());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (notification.getVisibility() != null) {
|
|
187
|
+
androidNotificationMap.putInt("visibility", notification.getVisibility());
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
notificationMap.putMap("android", androidNotificationMap);
|
|
191
|
+
return notificationMap;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
static RemoteMessage remoteMessageFromReadableMap(ReadableMap readableMap) {
|
|
195
|
+
RemoteMessage.Builder builder = new RemoteMessage.Builder(readableMap.getString(KEY_TO));
|
|
196
|
+
|
|
197
|
+
if (readableMap.hasKey(KEY_TTL)) {
|
|
198
|
+
builder.setTtl(readableMap.getInt(KEY_TTL));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (readableMap.hasKey(KEY_MESSAGE_ID)) {
|
|
202
|
+
builder.setMessageId(readableMap.getString(KEY_MESSAGE_ID));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (readableMap.hasKey(KEY_MESSAGE_TYPE)) {
|
|
206
|
+
builder.setMessageType(readableMap.getString(KEY_MESSAGE_TYPE));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (readableMap.hasKey(KEY_COLLAPSE_KEY)) {
|
|
210
|
+
builder.setCollapseKey(readableMap.getString(KEY_COLLAPSE_KEY));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (readableMap.hasKey(KEY_DATA)) {
|
|
214
|
+
ReadableMap messageData = readableMap.getMap(KEY_DATA);
|
|
215
|
+
ReadableMapKeySetIterator iterator = messageData.keySetIterator();
|
|
216
|
+
|
|
217
|
+
while (iterator.hasNextKey()) {
|
|
218
|
+
String key = iterator.nextKey();
|
|
219
|
+
builder.addData(key, messageData.getString(key));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return builder.build();
|
|
224
|
+
}
|
|
225
|
+
}
|