Skip to content

Commit f23b7e3

Browse files
committed
Migration of flutter/plugins#1900
1 parent 4157ee3 commit f23b7e3

File tree

5 files changed

+483
-6
lines changed

5 files changed

+483
-6
lines changed

packages/firebase_messaging/README.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,77 @@ Note: When you are debugging on Android, use a device or AVD with Google Play se
5454
<category android:name="android.intent.category.DEFAULT" />
5555
</intent-filter>
5656
```
57-
57+
#### Optionally handle background messages
58+
59+
By default background messaging is not enabled. To handle messages in the background:
60+
61+
1. Add an Application.java class to your app
62+
63+
```
64+
package io.flutter.plugins.firebasemessagingexample;
65+
66+
import io.flutter.app.FlutterApplication;
67+
import io.flutter.plugin.common.PluginRegistry;
68+
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
69+
import io.flutter.plugins.GeneratedPluginRegistrant;
70+
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
71+
72+
public class Application extends FlutterApplication implements PluginRegistrantCallback {
73+
@Override
74+
public void onCreate() {
75+
super.onCreate();
76+
FlutterFirebaseMessagingService.setPluginRegistrant(this);
77+
}
78+
79+
@Override
80+
public void registerWith(PluginRegistry registry) {
81+
GeneratedPluginRegistrant.registerWith(registry);
82+
}
83+
}
84+
```
85+
1. Set name property of application in `AndroidManifest.xml`
86+
```
87+
<application android:name=".Application" ...>
88+
```
89+
1. Define a top level Dart method to handle background messages
90+
```
91+
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
92+
if (message.containsKey('data')) {
93+
// Handle data message
94+
dynamic data = message['data'];
95+
}
96+
97+
if (message.containsKey('notification')) {
98+
// Handle notification message
99+
dynamic notification = message['notification'];
100+
}
101+
102+
// Or do other work.
103+
}
104+
```
105+
Note: the protocol of `data` and `notification` are in line with the
106+
fields defined by a [RemoteMessage](https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/RemoteMessage).
107+
1. Set `onBackgroundMessage` handler when calling `configure`
108+
```
109+
_firebaseMessaging.configure(
110+
onMessage: (Map<String, dynamic> message) async {
111+
print("onMessage: $message");
112+
_showItemDialog(message);
113+
},
114+
onBackgroundMessage: myBackgroundMessageHandler,
115+
onLaunch: (Map<String, dynamic> message) async {
116+
print("onLaunch: $message");
117+
_navigateToItemDetail(message);
118+
},
119+
onResume: (Map<String, dynamic> message) async {
120+
print("onResume: $message");
121+
_navigateToItemDetail(message);
122+
},
123+
);
124+
```
125+
Note: `configure` should be called early in the lifecycle of your application
126+
so that it can be ready to receive messages as early as possible. See the
127+
example app for a demonstration.
58128
59129
### iOS Integration
60130

packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ public class FirebaseMessagingPlugin extends BroadcastReceiver
4141
public static void registerWith(Registrar registrar) {
4242
final MethodChannel channel =
4343
new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_messaging");
44+
final MethodChannel backgroundCallbackChannel =
45+
new MethodChannel(
46+
registrar.messenger(), "plugins.flutter.io/firebase_messaging_background");
4447
final FirebaseMessagingPlugin plugin = new FirebaseMessagingPlugin(registrar, channel);
4548
registrar.addNewIntentListener(plugin);
4649
channel.setMethodCallHandler(plugin);
50+
backgroundCallbackChannel.setMethodCallHandler(plugin);
51+
52+
FlutterFirebaseMessagingService.setBackgroundChannel(backgroundCallbackChannel);
4753
}
4854

4955
private FirebaseMessagingPlugin(Registrar registrar, MethodChannel channel) {
@@ -99,7 +105,40 @@ private Map<String, Object> parseRemoteMessage(RemoteMessage message) {
99105

100106
@Override
101107
public void onMethodCall(final MethodCall call, final Result result) {
102-
if ("configure".equals(call.method)) {
108+
/* Even when the app is not active the `FirebaseMessagingService` extended by
109+
* `FlutterFirebaseMessagingService` allows incoming FCM messages to be handled.
110+
*
111+
* `FcmDartService#start` and `FcmDartService#initialized` are the two methods used
112+
* to optionally setup handling messages received while the app is not active.
113+
*
114+
* `FcmDartService#start` sets up the plumbing that allows messages received while
115+
* the app is not active to be handled by a background isolate.
116+
*
117+
* `FcmDartService#initialized` is called by the Dart side when the plumbing for
118+
* background message handling is complete.
119+
*/
120+
if ("FcmDartService#start".equals(call.method)) {
121+
long setupCallbackHandle = 0;
122+
long backgroundMessageHandle = 0;
123+
try {
124+
Map<String, Long> callbacks = ((Map<String, Long>) call.arguments);
125+
setupCallbackHandle = callbacks.get("setupHandle");
126+
backgroundMessageHandle = callbacks.get("backgroundHandle");
127+
} catch (Exception e) {
128+
Log.e(TAG, "There was an exception when getting callback handle from Dart side");
129+
e.printStackTrace();
130+
}
131+
FlutterFirebaseMessagingService.setBackgroundSetupHandle(
132+
this.registrar.context(), setupCallbackHandle);
133+
FlutterFirebaseMessagingService.startBackgroundIsolate(
134+
this.registrar.context(), setupCallbackHandle);
135+
FlutterFirebaseMessagingService.setBackgroundMessageHandle(
136+
this.registrar.context(), backgroundMessageHandle);
137+
result.success(true);
138+
} else if ("FcmDartService#initialized".equals(call.method)) {
139+
FlutterFirebaseMessagingService.onInitialized();
140+
result.success(true);
141+
} else if ("configure".equals(call.method)) {
103142
FirebaseInstanceId.getInstance()
104143
.getInstanceId()
105144
.addOnCompleteListener(

0 commit comments

Comments
 (0)