<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aqueel Aboobacker</title>
    <description>The latest articles on DEV Community by Aqueel Aboobacker (@aqueel).</description>
    <link>https://dev.to/aqueel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F571496%2F2a4f9624-7cb5-492e-a8c9-d29e688a72bf.png</url>
      <title>DEV Community: Aqueel Aboobacker</title>
      <link>https://dev.to/aqueel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aqueel"/>
    <language>en</language>
    <item>
      <title>This is why you need to use a factory constructor</title>
      <dc:creator>Aqueel Aboobacker</dc:creator>
      <pubDate>Sun, 06 Mar 2022 02:53:35 +0000</pubDate>
      <link>https://dev.to/aqueel/this-is-why-you-need-to-use-a-factory-constructor-kbm</link>
      <guid>https://dev.to/aqueel/this-is-why-you-need-to-use-a-factory-constructor-kbm</guid>
      <description>&lt;p&gt;In Dart, we can write multiple constructors for a class which allows different types of initialization. Writing factory keyword in front of a normal constructor or a named constructor will make it a factory constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyClass {
   // ...
   factory MyClass() {
     //..
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are three use cases for a factory constructor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The constructor is expensive, so you want to return an existing instance – if possible – instead of creating a new one.&lt;/li&gt;
&lt;li&gt;To implement singleton pattern&lt;/li&gt;
&lt;li&gt;You want to return a subclass instance instead of the class itself.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The warehouse
&lt;/h2&gt;

&lt;p&gt;The is the first use case where the constructor is expensive and you want to avoid the expensive work if possible. And this works exactly like a warehouse. Let’s say there is a warehouse for expensive shoes and a customer ordered a pair of shoes. Now the warehouse owner first looks if he has the stock available for that particular product. If it is available then he will deliver the order immediately. Otherwise, he will ask the production team to build new ones. This is exactly how the first use case works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Product {

  // private cache
  static final _shelf = &amp;lt;String, Product&amp;gt;{};

  factory Product(String productId) {
     return _shelf.putIfAbsent(
        productId, () =&amp;gt; Product._buildNewProduct(productId));
  }

  Product._buildNewProduct(String productId) {
    //..
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The “underscore” in front of a variable or a method will make it private to the class. Here running &lt;code&gt;_buildNewProduct&lt;/code&gt; method is expensive and we decided to avoid calling it every time if possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The singleton pattern
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of class to one single instance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is useful when only one instance of that class is needed throughout the application. The most common use case is a local storage database. We need only a single instance of that class throughout the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LocalStorage {

  static final _instance = LocalStorage._internal();

  factory LocalStorage() {
     return _instance;
  }

  LocalStorage._internal();

  Future&amp;lt;void&amp;gt; save(key, val) async {
    //.. 
  }

  Future read(key) async {
    //..
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Returning a subclass instance
&lt;/h2&gt;

&lt;p&gt;There will be situations where you need to return subclass instance where constructor will act like instance factory which return appropriate subclass based on provided input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class Shape {
  double area();

  factory Shape.fromType(String type) {
    if (type == 'square') return Square();
    if (type == 'circle') return Circle();
    throw Exception("unknown type");
  }
}

class Square implements Shape {
  double side = 5;

  @override
  double  area() =&amp;gt; pow(side, 2);

}

class Circle implements Shape {
  double radius = 5;

  @override
  double  area() =&amp;gt; pi * pow(radius, 2);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the abstract base class for returning subclass instances based on how the factory constructer is called. This is a simplified way to using the popular factory design pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var shape = Shape.fromType("square");
print(shape.area());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance the factory keyword will be confusing, and you will limit yourself into a single use case or even avoiding it completely. But when you look deeper and understand the concepts you will fall in love with this. This is an important feature of Dart programming language.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>flutter</category>
      <category>dart</category>
    </item>
    <item>
      <title>Flutter Firebase Messaging: Where everyone makes mistakes!</title>
      <dc:creator>Aqueel Aboobacker</dc:creator>
      <pubDate>Mon, 01 Feb 2021 14:36:17 +0000</pubDate>
      <link>https://dev.to/aqueel/flutter-firebase-messaging-where-everyone-makes-mistakes-3g0i</link>
      <guid>https://dev.to/aqueel/flutter-firebase-messaging-where-everyone-makes-mistakes-3g0i</guid>
      <description>&lt;p&gt;When I first got to integrate firebase messaging to flutter, I read the official documentation and many Medium articles and still failed to do it in the right way. There are many reasons for that: Articles I read were not beginner-friendly and also they missed few things. After going through the Github issues and few developer forums I finally understood the right way of doing it.&lt;/p&gt;

&lt;p&gt;In this tutorial, I will try to teach you how to integrate firebase messaging (push notification) into your flutter project without getting an error. So let’s get started.&lt;/p&gt;

&lt;h4&gt;
  
  
  STEP 1: 💥 Create Firebase project
&lt;/h4&gt;

&lt;p&gt;log in to firebase console &lt;a href="https://console.firebase.google.com/u/0/" rel="noopener noreferrer"&gt;https://console.firebase.google.com/u/0/&lt;/a&gt;&lt;br&gt;
Click on add project, enter the name of your project and click the continue button, and follow the wizard with a couple of clicks and the project will be created&lt;/p&gt;
&lt;h4&gt;
  
  
  STEP 2: 📱Add Android app
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First, click on the Android icon to add Android app&lt;br&gt;
Now a five-step wizard will appear. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the package name which will be in the &lt;code&gt;android/app/build.gralde&lt;/code&gt; file, look for &lt;code&gt;applicationId&lt;/code&gt; in that file. Also, provide a nickname for the app (optional). Now click register.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the second step, download the &lt;code&gt;google-service.json&lt;/code&gt; file and move it to &lt;code&gt;[project]/android/app&lt;/code&gt; location&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the classpath to the &lt;code&gt;[project]/android/build.gradle&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {   
// Example existing classpath   
classpath 'com.android.tools.build:gradle:3.5.3'   
// Add the google services classpath   
classpath 'com.google.gms:google-services:4.3.4' 
}
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Add the apply plugin to the &lt;code&gt;[project]/android/app/build.gradle&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ADD THIS AT THE BOTTOM 
apply plugin: 'com.google.gms.google-services'
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;If you want to be notified in your app (via &lt;code&gt;onResume&lt;/code&gt; and &lt;code&gt;onLaunch&lt;/code&gt;, don't worry we will be defining these functions in the following steps) when the user clicks on a notification in the system tray include the following intent-filter within the &lt;code&gt;&amp;lt;activity&amp;gt;&lt;/code&gt; tag of your &lt;code&gt;android/app/src/main/AndroidManifest.xml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;intent-filter&amp;gt;
  &amp;lt;action android:name="FLUTTER_NOTIFICATION_CLICK" /&amp;gt;
  &amp;lt;category 
    android:name="android.intent.category.DEFAULT" /&amp;gt;
&amp;lt;/intent-filter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;h4&gt;
  
  
  STEP 3: 📱Add IOS app
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;First, click on the IOS icon to add the IOS app&lt;/li&gt;
&lt;li&gt;Now a five-step wizard will appear. on the first step; Enter the bundle id. Open &lt;code&gt;ios/Runner.xcworkspace&lt;/code&gt; using Xcode, you can find the bundle id there. Provide a nickname for the app for identifying in the future (optional). Now click register.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffck9g7ddu9b9v2jkcdc8.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;li&gt;Download GoogleService-info.list and drag and drop it inside the runner folder using Xcode
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F29wpzuiuooyrnj7u2bg4.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;li&gt;Now a window will appear, make sure you have checked everything like in the following image.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F815c4um9eyicwfmk0ouw.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;li&gt;We are good to go!. Skip all other steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  STEP 4: ⚡ Adding packages to Flutter
&lt;/h4&gt;

&lt;p&gt;Install the following dependencies in your Flutter project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:  
   firebase_core: &amp;lt;latest_version&amp;gt; 
   firebase_messaging: &amp;lt;latest_version&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  STEP 5: 🔥 Configuring firebase messaging
&lt;/h4&gt;

&lt;p&gt;Now import the firebase messaging package and override the &lt;code&gt;initState&lt;/code&gt; method of the home screen widget and add the following lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

class MyHomePage extends StatefulWidget {

  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() =&amp;gt; _MyHomePageState();
}

class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; {
  int _counter = 0;

  final _firebaseMessaging = FirebaseMessaging();

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  void initState() {

    // configure firebase messaging

    _firebaseMessaging.configure(
      onMessage: (Map&amp;lt;String, dynamic&amp;gt; message) async {
        print("onMessage: $message");
      },
      onLaunch: (Map&amp;lt;String, dynamic&amp;gt; message) async {
        print("onLaunch: $message");
      },
      onResume: (Map&amp;lt;String, dynamic&amp;gt; message) async {
        print("onResume: $message");
      },
    );

    // requesting permission, only for ios

    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(
            sound: true, badge: true, alert: true, provisional: true));


    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });


    // getting registration id
    _firebaseMessaging.getToken().then((String token) async {
      assert(token != null);
      print('Registration Id: $token');
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: &amp;lt;Widget&amp;gt;[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  STEP 6: ✉️ Handling the received message
&lt;/h4&gt;

&lt;p&gt;For example, the payload we are sending through the firebase API is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://fcm.googleapis.com/fcm/send 
Content-Type:application/json 
Authorization:key=&amp;lt;API_KEY&amp;gt;
{
   "notification": {
   "title": "New order recieved",
   "body": "2 items ordered"
   },
   "data": {
   "status": "done",
   "order_id": 2971,
   "click_action": "FLUTTER_NOTIFICATION_CLICK"
   },
   "to": "&amp;lt;device id&amp;gt;"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The structure of the message we receive on our phones is different for Android and IOS. So we need to convert it into a common structure before we access it. So we will write a function that takes the message as input and convert it based on the platform the code is running on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Map&amp;lt;String, dynamic&amp;gt; _convertMessage(Map&amp;lt;String, dynamic&amp;gt; message) {
    try {
      if (Platform.isIOS) {
        return {
          'title': message['aps']['alert']['title'],
          'body': message['aps']['alert']['body'],
          'order_id': message['order_id'],
          'status': message['status'],
        };
      } else {
        return {
          'title': message['notification']['title'],
          'body': message['notification']['body'],
          'order_id': message['data']['order_id'],
          'status': message['data']['status'],
        };
      }
    } catch (e) {
      return null;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we converted the message into the same structure, so it will be easy to access and do whatever we want with the received message.&lt;/p&gt;

&lt;p&gt;That's it!. We have now successfully integrated The final code after integration will be as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() =&amp;gt; _MyHomePageState();
}

class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; {
  int _counter = 0;

  final _firebaseMessaging = FirebaseMessaging();

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

    Map&amp;lt;String, dynamic&amp;gt; _convertMessage(Map&amp;lt;String, dynamic&amp;gt; message) {
        try {
          if (Platform.isIOS) {
            return {
              'title': message['aps']['alert']['title'],
              'body': message['aps']['alert']['body'],
              'order_id': message['order_id'],
              'status': message['status'],
            };
          } else {
            return {
              'title': message['notification']['title'],
              'body': message['notification']['body'],
              'order_id': message['data']['order_id'],
              'status': message['data']['status'],
            };
          }
        } catch (e) {
          return null;
        }
      }

    }

  @override
  void initState() {

    // configure firebase messaging

    _firebaseMessaging.configure(
      onMessage: (Map&amp;lt;String, dynamic&amp;gt; message) async {
        Map&amp;lt;String, dynamic&amp;gt; convertedMessage = _convertMessage(message);
                if(convertedMessage != null) {
                    // now do your stuff here
                }
      },
      onLaunch: (Map&amp;lt;String, dynamic&amp;gt; message) async {
        Map&amp;lt;String, dynamic&amp;gt; convertedMessage = _convertMessage(message);
                if(convertedMessage != null) {
                    // now do your stuff here
                }
      },
      onResume: (Map&amp;lt;String, dynamic&amp;gt; message) async {
           Map&amp;lt;String, dynamic&amp;gt; convertedMessage = _convertMessage(message);
                if(convertedMessage != null) {
                    // now do your stuff here
                }
      },
    );

    // requesting permission, only for ios
    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(
            sound: true, badge: true, alert: true, provisional: true));


    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });


    // getting registration id
    _firebaseMessaging.getToken().then((String token) async {
      assert(token != null);
      print('Registration Id: $token');
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: &amp;lt;Widget&amp;gt;[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  📝 Things to note
&lt;/h4&gt;

&lt;p&gt;By default background messaging is not enabled. Background messaging is not receiving messages while the app is running in the background, it is only used for special cases. And this feature is only available for Android. So I recommend you to not care too much about this. &lt;code&gt;run tab&lt;/code&gt; in Android Studio will log the following message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;E/FlutterFcmService(15395): Fatal: failed to find callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error message is coming from startBackgroundIsolate which is used for allowing handling background messages. If you don’t want to handle background messages then you can safely ignore this error message.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
