<?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: Olamide Gabriel</title>
    <description>The latest articles on DEV Community by Olamide Gabriel (@lordlamee).</description>
    <link>https://dev.to/lordlamee</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%2F504831%2F4024f179-bd98-4c5a-9cbf-466168be671b.jpeg</url>
      <title>DEV Community: Olamide Gabriel</title>
      <link>https://dev.to/lordlamee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lordlamee"/>
    <language>en</language>
    <item>
      <title>Simplifying Null Safety in Flutter</title>
      <dc:creator>Olamide Gabriel</dc:creator>
      <pubDate>Wed, 29 Dec 2021 20:43:42 +0000</pubDate>
      <link>https://dev.to/lordlamee/simplifying-null-safety-in-flutter-cph</link>
      <guid>https://dev.to/lordlamee/simplifying-null-safety-in-flutter-cph</guid>
      <description>&lt;p&gt;&lt;strong&gt;INTRODUCTION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you ever run into the red screen of horror while debugging a flutter app?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1637047117922%2FTjKlGFJap.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1637047117922%2FTjKlGFJap.jpeg" alt="null.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I mean, if you haven’t, are you a Flutter developer at all?&lt;/p&gt;

&lt;p&gt;Out of numerous reasons for your app to relay your error in such a manner, null errors are one of the most common. In an attempt to eliminate this and the numerous null errors that occur while building/debugging your app, the great Flutter and Dart team introduced Null Safety.&lt;/p&gt;

&lt;p&gt;In simple terms, Null Safety allows the dart analyser to detect possible null errors pre-compilation, that is, before you even run your app. It ensures proper notifications of possible null data that could break your app while running.&lt;/p&gt;

&lt;p&gt;This article is for you, if&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You understand the basics of data types in Dart.&lt;/li&gt;
&lt;li&gt;You know a bit about classes, objects, i.e. the basics of OOP in Dart.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Else, you might want to go through the  &lt;a href="https://dart.dev/docs" rel="noopener noreferrer"&gt;Dart documentation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we will discuss the syntax changes and what they mean with the introduction of Null Safety.&lt;/p&gt;

&lt;p&gt;You may have seen characters such as "?", "!", and "??", and keywords such as "late".They are the main code additions you are required to understand.&lt;/p&gt;

&lt;p&gt;For the dart analyser to help you convert your runtime errors to "code time" errors, it needs some information. Before Null Safety, all variables were particularly nullable, so developers may forget to check if these variables are null, causing the red screen of death during debugging quite often or crash during production in the worst-case scenario. The analyser needs to know what variables might be null or will never be null.&lt;/p&gt;

&lt;p&gt;Before Null Safety, you would create a variable like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;///BEFORE
int myFavoriteNumber = 5;
//OR
int myFavoriteNumber;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first instance, we assigned myFavoriteNumber a value of 5. Although, along the line, we could assign it a value of null by writing&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;myFavoriteNumber = null;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in the second instance, myFavoriteNumber was null from the start.&lt;/p&gt;

&lt;p&gt;However, with Null Safety present, the rules have changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Instance 1
int favoriteNonNull = 7;
# Instance 2
int? favoriteNullable;
#Instance 3
int? favoriteNullabe2 = 10;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instance 1: We created a non-nullable variable and assigned it a value of 7. What does this mean? We have simply told the dart analyser that this variable can and must &lt;strong&gt;NEVER&lt;/strong&gt; be null. It means you must assign it a value at the point of creation, and you could &lt;strong&gt;NEVER&lt;/strong&gt; assign it a null value in the future. Going against any of these would force the dart analyser to scream in your face.&lt;/p&gt;

&lt;p&gt;Instance 2&amp;amp;3: We added a "?" right in front of the data type. It tells the analyser that "favoriteNullable" can be null. Thus, in cases where a non-nullable variable is required, the dart analyser should remind us to do a &lt;strong&gt;null check&lt;/strong&gt;. You can mess with this variable and assign it a null value. The analyser is your guide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you perform null checks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While writing Dart, which is an OOP language, you might find yourself using objects a lot with attributes/properties that may have null values. Your objects could be null as well as variables. Not to worry, "?" and "??" help with this issue.&lt;/p&gt;

&lt;p&gt;Let us examine a simple class "Dog" with attributes "name", "colour", and "weight".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Dog{
String? name;
String? colorName;
int? weight;
Dog({this.name,this.colorName,this.weight});
}

Dog? nullableDog;
Dog? nullableDog2 = Dog(
name :  "Jack",
colorName:  "Brown",
weight : 20,
);
Dog nonNullableDog = Dog(
name :  "Finn",
weight : 18,
);
#Extra variable for demo purposes
int? demoVariable = 30;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The easiest and most common way to perform a null check is using an &lt;strong&gt;if&lt;/strong&gt; statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(variable != null){
//use variable
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, we want to explore how the characters mentioned above can help us instead.&lt;br&gt;
For instance, say you're to use a nullable String in a Text widget which would not take nullable strings as a parameter. "??" comes in handy as you can use it to perform a quick null check and provide an alternative for the widget, thereby preventing possible crashes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String? parameter;
//Some Widget Tree
...
Text(
parameter ?? "Alternative Text",
)
...
//Some Widget Tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The dart analyser won't be too happy about an absence of a null check and alternative in this scenario.&lt;/p&gt;

&lt;p&gt;What if we wanted the name of our "nullableDog2" created above?&lt;/p&gt;

&lt;p&gt;Recall that "nullableDog2" is a nullable object with the nullable attribute "name". Did that confuse you? It simply means our "nullableDog2" may be null, and even if it isn't, its attribute name may be null as well. If we use this value in our Text widget, we would need to perform some extra checks. "?" allows you to perform a quick null check on an object while accessing its attributes. It saves you a couple of lines of code and makes objects easier to use within widgets.&lt;/p&gt;

&lt;p&gt;Here’s a brief demonstration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Some Widget Tree
...
Text(
nullableDog2?.name ?? "Alternative Text",
)
...
//Some Widget Tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dart analyser isn't perfect and sometimes would not realise some things a developer would. For example, you might be 100% sure a variable you have created to be nullable would not be null at the point you wish to use it. You want to shut the analyser up and tell it you know better. That's fine, but it comes with the risk of crashing your app. You need to be  100% sure. Dart has provided "!" to help silence the edit time warnings.&lt;/p&gt;

&lt;p&gt;A quick demo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String? parameter;

//Written some magic somewhere to make sure "parameter" isn't null when I need it...
//Some Widget Tree
...
Text(
parameter!,
)
...
//Some Widget Tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String? parameter;

//Some Widget Tree
...
if(parameter != null) //the analyzer may not detect this check
Text(
parameter!,
)
...
//Some Widget Tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let's talk about the &lt;strong&gt;late&lt;/strong&gt; keyword. Referencing the meaning of the word “late”, which means "not on time", by using this keyword, you are simply telling Dart that your variable is not going to be null, but you are not going to assign a value immediately it's created. You're going to assign it a value a little bit &lt;strong&gt;late&lt;/strong&gt;r before it is used.&lt;br&gt;
This is useful for variables that are expensive to create.&lt;br&gt;
Note: Failure to assign a value to late variables would cause your app to crash/errors during debugging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Inside some stateful widget
...
late AnimationController controller;
@override
initState(){
super.initState();
controller = AnimationController(
vsync:this,
);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have covered the basics of null safety and the keywords you would mainly be dealing with. I hope this will help you prevent more null errors in the future!&lt;/p&gt;

&lt;p&gt;For more examples and active practice, check out &lt;a href="https://dartpad.dev/workshops.html?webserver=https://dartpad-workshops-io2021.web.app/null_safety_workshop" rel="noopener noreferrer"&gt;intro to null safety by the Dart team&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If this was useful for you, be sure to leave a like and comment, and please share. Thank you!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>nullsafety</category>
      <category>dart</category>
    </item>
    <item>
      <title>Automating Push Notifications in Flutter with Firebase Cloud Functions and OneSignal.</title>
      <dc:creator>Olamide Gabriel</dc:creator>
      <pubDate>Sun, 06 Jun 2021 21:24:31 +0000</pubDate>
      <link>https://dev.to/lordlamee/automating-push-notifications-in-flutter-with-firebase-cloud-functions-and-onesignal-537b</link>
      <guid>https://dev.to/lordlamee/automating-push-notifications-in-flutter-with-firebase-cloud-functions-and-onesignal-537b</guid>
      <description>&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@jamie452?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jamie Street&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/notifications?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check my &lt;a href="https://dev.to/lordlamee/implementing-push-notifications-with-flutter-and-onesignal-part-1-3690"&gt;previous article&lt;/a&gt; to learn how to set up OneSignal in Flutter.&lt;/p&gt;

&lt;p&gt;Your database is going to get updated from time to time, and most times when they do, you want to inform your users about this change through push notifications.&lt;/p&gt;

&lt;p&gt;What do you do when you need to send notifications to hundreds of users based on an update to your FireStore collection?&lt;/p&gt;

&lt;p&gt;Lucky for us, OneSignal has an easy-to-use API that can be integrated with Firebase Cloud functions.&lt;/p&gt;

&lt;p&gt;Enough of the talks, let's automate our push notifications!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Requirements&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You must have set up firebase authentication in your Flutter app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have not set up authentication in your app, check out the &lt;a href="https://firebase.flutter.dev/docs/auth/usage/" rel="noopener noreferrer"&gt;official FlutterFire documentation on Firebase Authentication with Flutter&lt;/a&gt; to get started. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 1&lt;/em&gt;&lt;br&gt;
OneSignal provides unique &lt;code&gt;player IDs&lt;/code&gt; to identify different devices. You need to save the player IDs of every user that registers on your app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a Firestore collection named 'onesignalids' where you would save the player IDs for each user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add two fields to the collection.&lt;br&gt;
(i) The &lt;code&gt;customer_id&lt;/code&gt; field where you save the user ID of a particular user.&lt;br&gt;
(ii) An array of strings where you save the player ID of that user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the &lt;code&gt;savePlayerId&lt;/code&gt; method to save the user's player id. This method should be invoked when the user registers or logs in depending on your use case.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What this method does is to create a new list of player-ids for a user, if it doesn't already exist.&lt;br&gt;
&lt;code&gt;FieldValue.arrayUnion()&lt;/code&gt; ensures that there are no duplicate player-ids in the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;savePlayerId() async {
//Call the required instances.
    final firebaseAuth = FirebaseAuth.instance;
    final firestore = FirebaseFirestore.instance;
    try {
      final subState = await OneSignal.shared.getPermissionSubscriptionState();
      final deviceId = subState.subscriptionStatus.userId;
      final firestoreDeviceIdReference = await firestore
          .collection("onesignalids")
          .where("customer_id", isEqualTo: firebaseAuth.currentUser?.uid ?? "")
          .get();
      if (firestoreDeviceIdReference != null &amp;amp;&amp;amp;
          firestoreDeviceIdReference.size != 0) {
        await firestore
            .collection("onesignalids")
            .doc(firestoreDeviceIdReference.docs[0].id)
            .update({
          "player_ids": FieldValue.arrayUnion([deviceId])
        });
      } else {
        await firestore.collection("onesignalids").add({
          "customer_id": firebaseAuth.currentUser?.uid ?? "",
          "player_ids": [deviceId],
        });
      }
    } catch (e) {
      print("ERROR $e");
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, you create your notifications collection on Firebase FireStore.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a FireStore collection named 'notifications' where you would save the notifications for all users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following fields to the collection.&lt;br&gt;
(i) The &lt;code&gt;customer_id&lt;/code&gt; field which takes the user ID of the recipient of the notification.&lt;br&gt;
(ii) The &lt;code&gt;title&lt;/code&gt; field that takes the title of your notification.&lt;br&gt;
(iii) The &lt;code&gt;detail&lt;/code&gt; field that takes in the notification payload.&lt;br&gt;
(iv) The &lt;code&gt;time&lt;/code&gt; field that takes the timestamp of the notification.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PS: You can name these fields however you want to, as long as you remain consistent.&lt;/p&gt;

&lt;p&gt;IMPORTANT: To be able to use cloud functions, you need to upgrade your project's plan to the Blaze plan. You can easily upgrade in the settings section of your project.&lt;/p&gt;

&lt;p&gt;To be able to use cloud functions, you must have Node installed. This gives you access to run npm functions.&lt;/p&gt;

&lt;p&gt;If you don't already have firebase tools installed,&lt;br&gt;
run &lt;code&gt;npm install -g firebase-tools&lt;/code&gt; in the command prompt.&lt;/p&gt;

&lt;p&gt;Ensure to run &lt;code&gt;firebase login&lt;/code&gt; in the command prompt to log in on your device.&lt;/p&gt;

&lt;p&gt;Let's create and deploy our cloud function!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new folder and run &lt;code&gt;firebase init functions&lt;/code&gt; in cmd.&lt;/li&gt;
&lt;li&gt;Select your Firebase project and be sure to install dependencies with npm.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also, run &lt;code&gt;npm install https&lt;/code&gt; as you will need it to make API calls.&lt;/p&gt;

&lt;p&gt;We will make use of Javascript to write our cloud functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82tv9eovooh8k9d08tb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82tv9eovooh8k9d08tb9.png" alt="CMD IMAGE" width="800" height="431"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falyelbly54kq57ve577z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falyelbly54kq57ve577z.png" alt="CMD IMAGE" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the index.js in the folder in your code editor (VSCode or any preferred editor) and follow the next steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, you need to load the modules you will require for this project.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config.functions);
 const https = require("https");

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

&lt;/div&gt;


&lt;p&gt;Next, we create a method that handles sending of push notifications via an API call.&lt;/p&gt;

&lt;p&gt;This function takes in our push notification data containing our message and the player IDs of recipients and makes a request to the OneSignal server to have them sent.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sendNotification = (data) =&amp;gt; {
  var headers = {
    "Content-Type": "application/json; charset=utf-8",
    Authorization: "Basic $YOUR ONESIGNAL API KEY",
  };

  var options = {
    host: "onesignal.com",
    port: 443,
    path: "/api/v1/notifications",
    method: "POST",
    headers: headers,
  };

  var req = https.request(options, (res) =&amp;gt; {
    console.log("statusCode:", res.statusCode);
    console.log("headers:", res.headers);
    res.on("data", (data) =&amp;gt; {
      console.log("Response:");
      console.log(JSON.parse(data));
    });
  });


  req.on("error", (e) =&amp;gt; {
    console.log("ERROR:");
    console.log(e);
  });

  req.write(JSON.stringify(data));
  req.end();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we assign a function that is executed when a document is created on our notifications collection in FireStore to an export.&lt;/p&gt;

&lt;p&gt;The 'pushNotificationMessage' export function is responsible for fetching the player IDs and notification message, and sending it to the OneSignal server for delivery to the recipients.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.pushNotificationMessage = functions.firestore.document("notifications/{id}").onCreate(async (snapshot, context) =&amp;gt; {
 //OnCreate function will go here. 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's walk through the 'onCreate' callback.&lt;/p&gt;

&lt;p&gt;First, we fetch the player ID of the notification's recipient.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  var playerIdsDocs = await admin.firestore().collection("onesignalids")
  .where("customer_id","==" , snapshot.data().customer_id,)
  .get(); //this fetches the document containing the user's player //ids
  var playerIds = [];
  if(!playerIdsDocs.empty){
     playerIdsDocs.forEach((playerIdSingleDoc)=&amp;gt;{
       playerIds = playerIdSingleDoc.data().player_ids; // this //assigns the player id(s) to the list variable above.
     });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note : Only one document would be fetched for each user.&lt;/p&gt;

&lt;p&gt;Next, we save the notification in a message variable.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var message = {
        app_id: "YOUR APP ID",
        contents: { en : snapshot.data().detail },
        headings: { en : snapshot.data().title },
        include_player_ids : playerIds,
      };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, for the callback, we call the 'sendNotification' function we defined earlier.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   if(!playerIds.empty){
      return sendNotification(message);
   }
      else{
        return ;
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The only thing left to do is to open the terminal and run &lt;code&gt;firebase deploy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Every time the notifications collection is updated, OneSignal will send a notification on your behalf.&lt;/p&gt;

&lt;p&gt;The complete cloud functions code can be viewed below.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



</description>
      <category>flutter</category>
      <category>cloudfunctions</category>
      <category>firebase</category>
      <category>onesignal</category>
    </item>
    <item>
      <title>Implementing Push Notifications With Flutter and OneSignal-Part 1</title>
      <dc:creator>Olamide Gabriel</dc:creator>
      <pubDate>Fri, 04 Jun 2021 20:36:52 +0000</pubDate>
      <link>https://dev.to/lordlamee/implementing-push-notifications-with-flutter-and-onesignal-part-1-3690</link>
      <guid>https://dev.to/lordlamee/implementing-push-notifications-with-flutter-and-onesignal-part-1-3690</guid>
      <description>&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@jamie452?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jamie Street&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/notifications?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your users are definitely not going to be on your app for 24 hours every day. However, you might want to remind them to check your app, or notify them of new things happening in your app even when it's closed. You use Push Notifications to achieve this. And contrary to popular belief, they're really easy to implement with Flutter and OneSignal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get started
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Requirements
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;A OneSignal Account&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;
  
  
  Step One
&lt;/h5&gt;

&lt;p&gt;&lt;em&gt;Setup your firebase project&lt;/em&gt;&lt;br&gt;
Go to &lt;a href="https://firebase.google.com" rel="noopener noreferrer"&gt;https://firebase.google.com&lt;/a&gt; to get started.&lt;br&gt;
&lt;a href="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%2Fuploads%2Farticles%2F8d97pmojs5jr4fznsx28.png" class="article-body-image-wrapper"&gt;&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%2Fuploads%2Farticles%2F8d97pmojs5jr4fznsx28.png" alt="Firebase creation process image"&gt;&lt;/a&gt;&lt;br&gt;
You should have something like this on the console.&lt;/p&gt;

&lt;p&gt;On the next page, you could choose to enable or disable analytics. Your project should take a few seconds to be created depending on your internet connection&lt;/p&gt;

&lt;h5&gt;
  
  
  Step Two
&lt;/h5&gt;

&lt;p&gt;Setup your flutter project.&lt;br&gt;
-&lt;em&gt;create flutter project&lt;/em&gt;&lt;br&gt;
run &lt;code&gt;flutter create push_notifications_demo&lt;/code&gt; in your command line interface(command prompt).&lt;br&gt;
-&lt;em&gt;add your app to the firebase project&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Android&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click the android button as shown in the image below.&lt;br&gt;
&lt;a href="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%2Fuploads%2Farticles%2Fzbgn1rdvw55ebnyg1ljq.png" class="article-body-image-wrapper"&gt;&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%2Fuploads%2Farticles%2Fzbgn1rdvw55ebnyg1ljq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add your app credentials and download the config file.&lt;br&gt;
&lt;a href="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%2Fuploads%2Farticles%2Fzqb7yo8bzbzgnejmshcx.png" class="article-body-image-wrapper"&gt;&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%2Fuploads%2Farticles%2Fzqb7yo8bzbzgnejmshcx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; &lt;br&gt;
Your android package name is the "applicationId" in your app-level build.gradle file(android/app/build.gradle).&lt;br&gt;
Be sure to add the googleservices.json file to your project and set up the Firebase SDK as instructed in the process.&lt;/p&gt;

&lt;p&gt;Once you've followed the instructions correctly, you should see an android app in your project.&lt;/p&gt;

&lt;p&gt;-&lt;em&gt;setup Onesignal for your app&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into OneSignal and create a new app. You could choose to use the default organization or an organization of your own. No worries, you can always change it later.
.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add your firebase server key and sender ID.&lt;br&gt;
You can find these keys here.&lt;br&gt;
&lt;a href="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%2Fuploads%2Farticles%2F3u26rl8ki3srddjh060u.png" class="article-body-image-wrapper"&gt;&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%2Fuploads%2Farticles%2F3u26rl8ki3srddjh060u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the Android platform and Flutter as the SDK. &lt;br&gt;
You should now be able to see your application ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add firebase_core and one_signal_flutter plugin to your app.&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;dependencies:&lt;br&gt;
  flutter:&lt;br&gt;
    sdk: flutter&lt;br&gt;
  cupertino_icons: ^1.0.2&lt;br&gt;
  onesignal_flutter: ^2.6.3&lt;br&gt;
  firebase_core: ^1.1.0&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5. In your project level(android/build.gradle) build.gradle file, add the following line of code:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;repositories {&lt;br&gt;
        jcenter()&lt;br&gt;
        maven { url '&lt;a href="https://plugins.gradle.org/m2/" rel="noopener noreferrer"&gt;https://plugins.gradle.org/m2/&lt;/a&gt;' } //add this line&lt;br&gt;
    }&lt;br&gt;
  dependencies {&lt;br&gt;
        classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.6, 0.99.99]'&lt;br&gt;
     ...&lt;br&gt;
    }&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In your app level(android/app/build.gradle) build.gradle file, add the following line of code:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;apply plugin: 'com.android.application' //this already exits&lt;br&gt;
//add this line&lt;br&gt;
apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'&lt;br&gt;
...&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Great! You're all set up on Android.

**For iOS**

Requirements 
1. An apple developer account with an Admin role.
2. A Macbook with XCode 11+

Steps
1. Generate an iOS Push Certificate.
You can easily generate one using the [OneSignal provisioning tool ](https://onesignal.com/provisionatorhttps://onesignal.com/provisionatorhttps://onesignal.com/provisionator) here

2. Enable iOS push capability and extension service following the instructions on the [Official OneSignal documentation here](https://documentation.onesignal.com/docs/flutter-sdk-setup#step-4---enable-ios-push-capability-in-xcode-ios-apps-only)

We're done setting up!

Now, let's practice sending a push notification.

In the main.dart file of your project, we need to initialize the OneSignal plugin.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;import 'package:firebase_core/firebase_core.dart';&lt;br&gt;
import 'package:flutter/material.dart';&lt;br&gt;
import 'package:onesignal_flutter/onesignal_flutter.dart';&lt;/p&gt;

&lt;p&gt;void main() {&lt;br&gt;
  WidgetsFlutterBinding.ensureInitialized();&lt;br&gt;
  Firebase.initializeApp();&lt;br&gt;
  OneSignal.shared.init("YOUR ONESIGNAL APP ID", iOSSettings: {&lt;br&gt;
    OSiOSSettings.autoPrompt: false,&lt;br&gt;
    OSiOSSettings.inAppLaunchUrl: false&lt;br&gt;
  });&lt;br&gt;
  runApp(MyApp());&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run your app to initialize the plugin.

Next, on the Dashboard section of your application's OneSignal account, do the following:

1. Click on the "New Push" button shown below. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ebdwyc58k766x49iewf5.png)

2. Enter the title and message of your notification.

3. Click send to test device.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdc2xz4v0koh7a1ohjxf.png)
You should be redirected to a page of all users so you can add a test user.

4. You should find your device there. If you don't, run the app again. Click on options and add your device as a test user.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gxtg2zix4kjby9oqqji.png)

5. Go back and click on Send To Test Device. Select your device and send.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edi3i3i2sqsy6d2ci62v.png)

You've successfully sent your first notification!

Tip: Add handlers to your notifications to run functions at specific events.

To handle callbacks once notifications are received:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OneSignal.shared.setNotificationReceivedHandler((OSNotification notification) {&lt;br&gt;
    //This will be called whenever a notification is received&lt;br&gt;
});&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To handle callbacks when notifications are opened:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OneSignal.shared.setNotificationOpenedHandler((OSNotificationOpenedResult result) {&lt;br&gt;
  // This will be called whenever a notification is opened.&lt;br&gt;
});&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
And with this, you can send your users push notifications anytime you want!

[OneSignal's documentation](https://documentation.onesignal.com/docs/flutter-sdk) is very rich and easy to read. You can get more detail on features and methods available on the SDK.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>flutter</category>
      <category>onesignal</category>
      <category>pushnotifications</category>
    </item>
  </channel>
</rss>
