I have built an application with flutter that works like a reminder.
How can I display notifications to the user even though the app is closed?
问题:
回答1:
For reminders i would recomend Flutter Local Notifications Plugin. It has a powerful scheduling api. From the documentation of local notification:
Scheduling when notifications should appear - Periodically show a notification (interval-based) - Schedule a notification to be shown daily at a specified time - Schedule a notification to be shown weekly on a specified day and time - Ability to handle when a user has tapped on a notification when the app is the foreground, background or terminated
And for push notification, you can use Firebase Cloud Messaging or one signal plugin or you can implement natively through platform-channels
Edit: You can also fire notifications according to specific conditions even if the app is terminated. This can be achevied by running dart code in the background. Quoting from the official faq:
Can I run Dart code in the background of an Flutter app? Yes, you can run Dart code in a background process on both iOS and Android. For more information, see the Medium article Executing Dart in the Background with Flutter Plugins and Geofencing.
回答2:
I have found a solution to this problem. We just have to register the Local Notification Plugin in the Application class.
First Create a class FlutterLocalNotificationPluginRegistrant, I have created this in Kotlin.
class FlutterLocalNotificationPluginRegistrant {
companion object {
fun registerWith(registry: PluginRegistry) {
if (alreadyRegisteredWith(registry)) {
Log.d("Local Plugin", "Already Registered");
return
}
FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
Log.d("Local Plugin", "Registered");
}
private fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
val key = FlutterLocalNotificationPluginRegistrant::class.java.canonicalName
if (registry.hasPlugin(key)) {
return true
}
registry.registrarFor(key)
return false
}
}}
Now create a Application class extending FlutterApplication and implement PluginRegistry.PluginRegistrantCallback.
class Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
}
override fun registerWith(registry: PluginRegistry?) {
if (registry != null) {
FlutterLocalNotificationPluginRegistrant.registerWith(registry)
}
}}
and register the Application class in the AndroidManifest.xml
<application
android:name="com.packagename.Application"/>
All done. Now write a function to show notification and call it from the background handler method of Firebase messaging.
Future _showNotificationWithDefaultSound(String title, String message) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'channel_id', 'channel_name', 'channel_description',
importance: Importance.Max, priority: Priority.High);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
'$title',
'$message',
platformChannelSpecifics,
payload: 'Default_Sound',
);
}
and call it like this.
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
if (message['data'] != null) {
final data = message['data'];
final title = data['title'];
final body = data['message'];
await _showNotificationWithDefaultSound(title, message);
}
return Future<void>.value();
}
回答3:
I have also faced this issue, So these are my learnings
In my Case : i am able to get notification in App-Resume or App-background state, but in App-Close state, I am not receiving notifification.
In this case our notification body was :
{notification: {body: null, title: null}, data: {body: hello, title: world}}
To Receive Notification in App-Closed state we changed notification to
{notification: {body: abc, title: abc}, data: {url: string, body: string, title: string}}
回答4:
You can use scheduled notifications in flutter.
var scheduledNotificationDateTime =
new DateTime.now().add(new Duration(seconds: 5));
var androidPlatformChannelSpecifics =
new AndroidNotificationDetails('your other channel id',
'your other channel name', 'your other channel description');
var iOSPlatformChannelSpecifics =
new IOSNotificationDetails();
NotificationDetails platformChannelSpecifics = new
NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.schedule(
0,
'scheduled title',
'scheduled body',
scheduledNotificationDateTime,
platformChannelSpecifics);
回答5:
The official firebase_messaging flutter plugin supports showing notification sent via FCM. Recently in v5.1.5 they added support for background message handling for andriod.
https://pub.dev/packages/firebase_messaging#515