[messaging] Support FCM data-only messages in the background
This commit is contained in:
parent
57ffa9bd3e
commit
7ce7f5ae58
|
@ -0,0 +1,43 @@
|
||||||
|
package io.invertase.firebase.messaging;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class MessagingSerializer {
|
||||||
|
public static WritableMap parseRemoteMessage(RemoteMessage message) {
|
||||||
|
WritableMap messageMap = Arguments.createMap();
|
||||||
|
WritableMap dataMap = Arguments.createMap();
|
||||||
|
|
||||||
|
if (message.getCollapseKey() != null) {
|
||||||
|
messageMap.putString("collapseKey", message.getCollapseKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.getData() != null) {
|
||||||
|
for (Map.Entry<String, String> e : message.getData().entrySet()) {
|
||||||
|
dataMap.putString(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messageMap.putMap("data", dataMap);
|
||||||
|
|
||||||
|
if (message.getFrom() != null) {
|
||||||
|
messageMap.putString("from", message.getFrom());
|
||||||
|
}
|
||||||
|
if (message.getMessageId() != null) {
|
||||||
|
messageMap.putString("messageId", message.getMessageId());
|
||||||
|
}
|
||||||
|
if (message.getMessageType() != null) {
|
||||||
|
messageMap.putString("messageType", message.getMessageType());
|
||||||
|
}
|
||||||
|
messageMap.putDouble("sentTime", message.getSentTime());
|
||||||
|
if (message.getTo() != null) {
|
||||||
|
messageMap.putString("to", message.getTo());
|
||||||
|
}
|
||||||
|
messageMap.putDouble("ttl", message.getTtl());
|
||||||
|
|
||||||
|
return messageMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package io.invertase.firebase.messaging;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.facebook.react.HeadlessJsTaskService;
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
|
||||||
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class RNFirebaseBackgroundMessagingService extends HeadlessJsTaskService {
|
||||||
|
@Override
|
||||||
|
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
|
||||||
|
Bundle extras = intent.getExtras();
|
||||||
|
if (extras != null) {
|
||||||
|
RemoteMessage message = intent.getParcelableExtra("message");
|
||||||
|
WritableMap messageMap = MessagingSerializer.parseRemoteMessage(message);
|
||||||
|
return new HeadlessJsTaskConfig(
|
||||||
|
"RNFirebaseBackgroundMessage",
|
||||||
|
messageMap,
|
||||||
|
10000,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ import android.content.IntentFilter;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.react.bridge.Arguments;
|
|
||||||
import com.facebook.react.bridge.Promise;
|
import com.facebook.react.bridge.Promise;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
@ -21,8 +20,6 @@ import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
import io.invertase.firebase.Utils;
|
import io.invertase.firebase.Utils;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
|
public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
|
||||||
private static final String TAG = "RNFirebaseMessaging";
|
private static final String TAG = "RNFirebaseMessaging";
|
||||||
|
|
||||||
|
@ -115,44 +112,11 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
|
||||||
Log.d(TAG, "Received new message");
|
Log.d(TAG, "Received new message");
|
||||||
|
|
||||||
RemoteMessage message = intent.getParcelableExtra("message");
|
RemoteMessage message = intent.getParcelableExtra("message");
|
||||||
WritableMap messageMap = buildMessageMap(message);
|
WritableMap messageMap = MessagingSerializer.parseRemoteMessage(message);
|
||||||
|
|
||||||
Utils.sendEvent(getReactApplicationContext(), "messaging_message_received", messageMap);
|
Utils.sendEvent(getReactApplicationContext(), "messaging_message_received", messageMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WritableMap buildMessageMap(RemoteMessage message) {
|
|
||||||
WritableMap messageMap = Arguments.createMap();
|
|
||||||
WritableMap dataMap = Arguments.createMap();
|
|
||||||
|
|
||||||
if (message.getCollapseKey() != null) {
|
|
||||||
messageMap.putString("collapseKey", message.getCollapseKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.getData() != null) {
|
|
||||||
for (Map.Entry<String, String> e : message.getData().entrySet()) {
|
|
||||||
dataMap.putString(e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
messageMap.putMap("data", dataMap);
|
|
||||||
|
|
||||||
if (message.getFrom() != null) {
|
|
||||||
messageMap.putString("from", message.getFrom());
|
|
||||||
}
|
|
||||||
if (message.getMessageId() != null) {
|
|
||||||
messageMap.putString("messageId", message.getMessageId());
|
|
||||||
}
|
|
||||||
if (message.getMessageType() != null) {
|
|
||||||
messageMap.putString("messageType", message.getMessageType());
|
|
||||||
}
|
|
||||||
messageMap.putDouble("sentTime", message.getSentTime());
|
|
||||||
if (message.getTo() != null) {
|
|
||||||
messageMap.putString("to", message.getTo());
|
|
||||||
}
|
|
||||||
messageMap.putDouble("ttl", message.getTtl());
|
|
||||||
|
|
||||||
return messageMap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RefreshTokenReceiver extends BroadcastReceiver {
|
private class RefreshTokenReceiver extends BroadcastReceiver {
|
||||||
|
|
|
@ -4,9 +4,12 @@ import android.content.Intent;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.react.HeadlessJsTaskService;
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
import com.google.firebase.messaging.RemoteMessage;
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
|
import io.invertase.firebase.Utils;
|
||||||
|
|
||||||
public class RNFirebaseMessagingService extends FirebaseMessagingService {
|
public class RNFirebaseMessagingService extends FirebaseMessagingService {
|
||||||
private static final String TAG = "RNFMessagingService";
|
private static final String TAG = "RNFMessagingService";
|
||||||
public static final String MESSAGE_EVENT = "messaging-message";
|
public static final String MESSAGE_EVENT = "messaging-message";
|
||||||
|
@ -16,19 +19,28 @@ public class RNFirebaseMessagingService extends FirebaseMessagingService {
|
||||||
public void onMessageReceived(RemoteMessage message) {
|
public void onMessageReceived(RemoteMessage message) {
|
||||||
Log.d(TAG, "onMessageReceived event received");
|
Log.d(TAG, "onMessageReceived event received");
|
||||||
|
|
||||||
Intent event;
|
|
||||||
|
|
||||||
if (message.getNotification() != null) {
|
if (message.getNotification() != null) {
|
||||||
// It's a notification, pass to the notification module
|
// It's a notification, pass to the Notifications module
|
||||||
event = new Intent(REMOTE_NOTIFICATION_EVENT);
|
Intent notificationEvent = new Intent(REMOTE_NOTIFICATION_EVENT);
|
||||||
event.putExtra("notification", message);
|
notificationEvent.putExtra("notification", message);
|
||||||
} else {
|
|
||||||
// It's a data message, pass to the messaging module
|
|
||||||
event = new Intent(MESSAGE_EVENT);
|
|
||||||
event.putExtra("message", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Broadcast it to the (foreground) RN Application
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(notificationEvent);
|
||||||
|
} else {
|
||||||
|
// It's a data message
|
||||||
|
// If the app is in the foreground we send it to the Messaging module
|
||||||
|
if (Utils.isAppInForeground(this.getApplicationContext())) {
|
||||||
|
Intent messagingEvent = new Intent(MESSAGE_EVENT);
|
||||||
|
messagingEvent.putExtra("message", message);
|
||||||
// Broadcast it so it is only available to the RN Application
|
// Broadcast it so it is only available to the RN Application
|
||||||
LocalBroadcastManager.getInstance(this).sendBroadcast(event);
|
LocalBroadcastManager.getInstance(this).sendBroadcast(messagingEvent);
|
||||||
|
} else {
|
||||||
|
// If the app is in the background we send it to the Headless JS Service
|
||||||
|
Intent headlessIntent = new Intent(this.getApplicationContext(), RNFirebaseBackgroundMessagingService.class);
|
||||||
|
headlessIntent.putExtra("message", message);
|
||||||
|
this.getApplicationContext().startService(headlessIntent);
|
||||||
|
HeadlessJsTaskService.acquireWakeLockNow(this.getApplicationContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
|
||||||
|
|
||||||
<receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"/>
|
<receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"/>
|
||||||
<receiver android:enabled="true" android:exported="true" android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver">
|
<receiver android:enabled="true" android:exported="true" android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import { AppRegistry } from 'react-native';
|
import { AppRegistry } from 'react-native';
|
||||||
import bootstrap from './src/main';
|
import bootstrap from './src/main';
|
||||||
|
import bgMessaging from './src/bgMessaging';
|
||||||
|
|
||||||
AppRegistry.registerComponent('ReactNativeFirebaseDemo', () => bootstrap);
|
AppRegistry.registerComponent('ReactNativeFirebaseDemo', () => bootstrap);
|
||||||
|
// Task registered to handle background data-only FCM messages
|
||||||
|
AppRegistry.registerHeadlessTask(
|
||||||
|
'RNFirebaseBackgroundMessage',
|
||||||
|
() => bgMessaging
|
||||||
|
);
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import RNfirebase from './../firebase';
|
||||||
|
|
||||||
|
export default async message => {
|
||||||
|
console.log('Message', message);
|
||||||
|
|
||||||
|
const notification = new RNfirebase.notifications.Notification();
|
||||||
|
notification
|
||||||
|
.setTitle('Background notification')
|
||||||
|
.setBody('Background body')
|
||||||
|
.setNotificationId('background')
|
||||||
|
.android.setChannelId('test')
|
||||||
|
.android.setClickAction('action')
|
||||||
|
.android.setPriority(RNfirebase.notifications.Android.Priority.Max);
|
||||||
|
|
||||||
|
await RNfirebase.notifications().displayNotification(notification);
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
Loading…
Reference in New Issue