Categories
Flutter

Flutter – Local push notifications

Create a Flutter project

To create a new project in Flutter execute the following command line in the terminal.

flutter create tryoutflutter

We are using tryoutflutter as the project name. It will create a folder with the name of the project. Inside the project, the files structure should like this:

Let’s look at the folders and files in the project.

android folder: this includes specific files to configure our Android application.

  • To get special permissions,
  • Firebase configuration,
  • To set a logo, splash screen, display name, etc,.

iOS folder, this includes specific files to configure our iOS application.

Build folder, this includes the debug application build APK. This will automatically create once you run the project.

lib folder, this includes Dart files. In this folder, we need to write and manage Dart code.

pubspec.yaml, in this file we can manage the packages (libraries), assets (images, icons, etc,.) that we will use for our application.

Dependencies

Have to install the following packages,

  • RxDart this package adds the additional capabilities to receive the sequence of events (stream) and controls (stream controllers),
  • Flutter local notifications to compose, schedule and manage notifications.

Android setup

Add an event receiver to receive scheduled notification while the application was not running in the foreground.

Paste the following code in AndroidManifest.xml file which is located in this <projectName>/android/app/src/main path.

<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>

iOS setup

For iOS add this code snippet in AppDelegate.swift file to receive notification, which is located in the following path <projectname>/ios/Runner/AppleDelegate.swift and also have to get permission from user to receive notifications.

To know more about UNUserNotificationCenter,

if #available(iOS 10.0, *) {
   UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}

Trigger Local Notifications

  • For iOS devices have to get permissions to receive notifications from our applications,
void _requestPermissions() {
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            IOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            MacOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );
  }
  • Call _requestPermissions() from initState() if the platform is iOS, the initState( ) will called once the widget is initialized,
@override
  void initState() {
    super.initState();
    if (Platform.isIOS) {
      _requestPermissions();
    }
  }
  • After those steps, we are ready to compose and receive notifications locally, let see an example to display a quick notification.
  • This will be used as a welcome greeting message during user onboard, or an alert if the event triggers.
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();
final BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject =
    BehaviorSubject<ReceivedNotification>();
final BehaviorSubject<String> selectNotificationSubject =
    BehaviorSubject<String>();
NotificationAppLaunchDetails notificationAppLaunchDetails;

class ReceivedNotification {
  final int id;
  final String title;
  final String body;
  final String payload;
  ReceivedNotification({
    @required this.id,
    @required this.title,
    @required this.body,
    @required this.payload,
  });
}
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  notificationAppLaunchDetails =
      await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
  var initializationSettingsAndroid =
      AndroidInitializationSettings('ic_launcher');
  var initializationSettingsIOS = IOSInitializationSettings(
      requestAlertPermission: false,
      requestBadgePermission: false,
      requestSoundPermission: false,
      onDidReceiveLocalNotification:
          (int id, String title, String body, String payload) async {
        didReceiveLocalNotificationSubject.add(ReceivedNotification(
            id: id, title: title, body: body, payload: payload));
      });
  var initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
  await flutterLocalNotificationsPlugin.initialize(initializationSettings,
      onSelectNotification: (String payload) async {
    if (payload != null) {
      debugPrint('notification payload: ' + payload);
    }
    selectNotificationSubject.add(payload);
  });
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter local push notification'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _requestPermissions() {
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            IOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            MacOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );
  }
  @override
  void initState() {
    super.initState();
    if (Platform.isIOS) {
      _requestPermissions();
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                onPressed: () {
                  showNotification();
                },
                child: Text("Show notification"),
              )
            ],
          ),
        ));
  }
}
Future<void> showNotification() async {
  const AndroidNotificationDetails androidPlatformChannelSpecifics =
  AndroidNotificationDetails(
    'your channel id', 
    'your channel name', 
    'your channel description',
    importance: Importance.max,
    priority: Priority.high,
    ticker: 'ticker'
  );
  
  const NotificationDetails platformChannelSpecifics = NotificationDetails(
    android: androidPlatformChannelSpecifics,
  );
  await flutterLocalNotificationsPlugin.show(
    1, 
    'plain title', 
    "Test Message", 
    platformChannelSpecifics,
    payload: 'item x'
  );
}
  • Function to display a scheduled notification, have to pass the following parameters channelId need to be unique, channelName, title, description, dateTime.
//ScheduleNotification
Future<void> scheduleNotificationFunction( String channelId, String channelName, String channelDes, String title, String description, DateTime dateTime) async {
  print("Notification schduled for $channelId");

  var platformChannelSpecifics = NotificationDetails(
      AndroidNotificationDetails(channelId, channelName, channelDes,
          playSound: true, enableLights: true, enableVibration: true),
      IOSNotificationDetails());

  await flutterLocalNotificationsPlugin.schedule(
      0, title, description, dateTime, platformChannelSpecifics);
}
  • Function to display a daily repeat notification, have to pass the following parameters channelId need to be unique, channelName, title, description, onlyTime 24 hour format.
//Daily repeat notification
Future<void> _repeatNotificationDailyAtSpecificTime() async {
  const AndroidNotificationDetails androidPlatformChannelSpecifics =
      AndroidNotificationDetails('repeating channel id',
          'repeating channel name', 'repeating description');
  const NotificationDetails platformChannelSpecifics =
      NotificationDetails(android: androidPlatformChannelSpecifics);
// ignore: deprecated_member_use
  await flutterLocalNotificationsPlugin.showDailyAtTime(2443, "Good Morning",
      "Message body", Time(10, 00, 00), platformChannelSpecifics);
}
  • This function to cancel a scheduled notification requires channelId
// To cancel notification
Future<void> _cancelNotification(id) async {
  await flutterLocalNotificationsPlugin.cancel(id);
}

Android

iOS

I have attached the complete code in this GitHub repo.

Leave a Reply

Your email address will not be published. Required fields are marked *