Firebase iOS Push Notification Flutter Step by Step

Firebase iOS Push Notification Flutter Step by Step

    We will focus on Flutter Firebase ios push notification step by step. I will share my experience how got notification successfully both from the post, firebase console and the serverside. 

    First go ahead create a new project and install the three packages below

      overlay_support:
      firebase_core:
      firebase_messaging:

    The first one is showing the notification and over, the next two are important for firebase notification. 

    After that in your main.dart file, remove all the code and place the code below

    import 'package:firebase_core/firebase_core.dart';
    import 'package:firebase_messaging/firebase_messaging.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';
    import 'package:overlay_support/overlay_support.dart';
    import 'package:flutter/material.dart';
    Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
      print("Handling a background message: ${message.messageId}");
    }
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Push Notification Demo',
          theme: ThemeData(
    
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(),
        );
      }
    }

    From the above code we understand we need to create a class name MyHomePage() and assign it to home property. 

    Let's go ahead and create stateful class name it my_home_page.dart inside main.dart and put the code below

    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
    
    
      @override 
      void initState(){
        
        super.initState();
      }
      
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    

    Inside initState() method we will ask for permission from user's in iOS. For that we need to create a method. After that, we will would be to receive message from Firebase. Firebase message will have title and body. 

    Because we want to be able to tap on the message and show in our app, so as the message arrarives we wanna put it in a model. 

    If we put that in a model we would be able to access that message outside of the scope of the class. So let's go ahead a create a new dart file and name it push_notification.dart and put the code below

    class PushNotification {
      PushNotification({
        this.title,
        this.body,
      });
      String? title;
      String? body;
    }

    We need another class to create. Since we want to tap on the notification, and open the notification on the app as an over lay and show the total number of notification we have received, so we will create a new class.

    We will call the new class notification_badge.dart and put the code below

    class NotificationBadge extends StatelessWidget {
      final int totalNotifications;
    
      const NotificationBadge({required this.totalNotifications});
    
      @override
      Widget build(BuildContext context) {
        return Container(
          width: 40.0,
          height: 40.0,
          decoration: new BoxDecoration(
            color: Colors.red,
            shape: BoxShape.circle,
          ),
          child: Center(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                '$totalNotifications',
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
          ),
        );
      }
    }

    Now we will go back to our main.dart class and inside MyHomePage class and put the variables there

      late int _totalNotifications;
      late final FirebaseMessaging _messaging;
      PushNotification? _notificationInfo;

    And after that we will create a new method. 

    The method name is requestAndRegisterNotification and put the code right below 

      void requestAndRegisterNotification() async {
        // 1. Initialize the Firebase app
        await Firebase.initializeApp();
    
        // 2. Instantiate Firebase Messaging
        _messaging = FirebaseMessaging.instance;
        FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
    
        // 3. On iOS, this helps to take the user permissions
        NotificationSettings settings = await _messaging.requestPermission(
          alert: true,
          badge: true,
          provisional: false,
          sound: true,
        );
    
        if (settings.authorizationStatus == AuthorizationStatus.authorized) {
          print('User granted permission');
          String? token = await _messaging.getToken();
          print("The token is "+token!);
          // For handling the received notifications
          FirebaseMessaging.onMessage.listen((RemoteMessage message) {
            // Parse the message received
            PushNotification notification = PushNotification(
              title: message.notification?.title,
              body: message.notification?.body,
            );
    
            setState(() {
              _notificationInfo = notification;
              _totalNotifications++;
            });
            if (_notificationInfo != null) {
              // For displaying the notification as an overlay
              showSimpleNotification(
                Text(_notificationInfo!.title!),
                leading: NotificationBadge(totalNotifications: _totalNotifications),
                subtitle: Text(_notificationInfo!.body!),
                background: Colors.cyan.shade700,
                duration: Duration(seconds: 2),
              );
            }
          });
        } else {
          print('User declined or has not accepted permission');
        }
      }

    The above method we will intialize firebase  and get an instance from firebase and ask for user permission from the iOS device and get a token for us from the device. we will use the token for sending notification to our device.

    After that we listen tot the firebase message and save the message body and title in PushNotification model.

    Call the above method from initState() and it should look like this 

      @override
      void initState() {
        registerNotification();
        _totalNotifications = 0;
        super.initState();
      }

    But if we want to open the notification on tap and show the correct info immediately, we need to do like below

      @override
      void initState() {
        registerNotification();
        FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
          PushNotification notification = PushNotification(
            title: message.notification?.title,
            body: message.notification?.body,
          );
          setState(() {
            _notificationInfo = notification;
            _totalNotifications++;
          });
        });
      
        _totalNotifications = 0;
        super.initState();
      }

    Next we need to work on the build method from of MyHomePage() class, so go ahead and replace the code build method code with the code below

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Notify'),
            brightness: Brightness.dark,
          ),
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'App for capturing Firebase Push Notifications',
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 20,
                ),
              ),
              SizedBox(height: 16.0),
              NotificationBadge(totalNotifications: _totalNotifications),
              SizedBox(height: 16.0),
              _notificationInfo != null
                  ? Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'TITLE: ${_notificationInfo!.title}',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 16.0,
                    ),
                  ),
                  SizedBox(height: 8.0),
                  Text(
                    'BODY: ${_notificationInfo!.body}',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 16.0,
                    ),
                  ),
                ],
              )
                  : Container(),
            ],
          ),
        );
      }

    Now, let's take a look at AppDelete.swift file for iOS

    import UIKit
    import Flutter
    import Firebase
    import FirebaseMessaging
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions:
     [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        FirebaseApp.configure()
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions:
      launchOptions)
      }
      override func application(_ application: UIApplication,
      didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    
       Messaging.messaging().apnsToken = deviceToken
       print("Token: \(deviceToken)")
       super.application(application,
       didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
     }
    }
    

    The last set up

    If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist

    You also need to set it up to Info.plist file to false

    Courses


    Recommended posts


    Recent posts