Academind Logo
Adding Flutter Push Notifcations to Flutter Apps

Adding Flutter Push Notifcations to Flutter Apps

Adding Push Notifications to Flutter apps involves a couple of steps and can be tricky. Here's a step-by-step guide.

Created by Maximilian Schwarzmüller

Push Notifications are a common feature in mobile apps, yet adding them can be tricky. Or at least, it involves a couple of steps that you have to go through.

This guide provides you with all the steps for Android and iOS apps built with Flutter.

#

How Do Push Notifications Work?

As you'll see below, it takes a couple of steps to add push notifications to an app. The reason for that mainly is security - after all you definitely don't want anyone to send out push messages to your apps' users.

Before we actually write any code, it's important to understand how push notifications work. You can skip this and jump right ahead to the Android or iOS parts but I strongly recommend that you pick up these important basics first!

Here's how Push Notifications are delivered to your app / the users of your app:

Push notifications are not sent directly from you to the devices, instead you have to use Apple's and Google's push services.

Let me explain this image.

First of all, you have to understand that you have two "ends": The frontend (your app, running on your users' devices) and the backend (a server you own which does the "behind the scenes" work). For more information on that, check out our Frontend vs Backend article.

We need both ends because you are most likely not just deliver a nice app UI to your users. Instead, your app probably should be able to offer certain features to your users.

For example:

  • Authentication (Signup & Login)

  • Storing data in a database (e.g. chat messages)

  • Storing uploaded images (e.g. user photos)

These are the kind of things your backend server does. Your Flutter app communicates with that server - all these features are by the way also covered in my Flutter course.

Back to the image.

The natural thing would be that you simply push a notification from your backend to the frontend and that then shows that notification on the user's device, even if your app is in the background at the moment.

But it doesn't work like that.

You absolutely can communicate like this with your app if it's in the foreground. But if it's in the background (i.e. currently not running), you need help from the device's operating system (iOS or Android) because it's the operating system that shows the notification in the end. You can't directly communicate with your app, if it's not running at the moment.

Both Android and iOS don't work such that they expose a simple API to which you can send a request, which then in turn what lead to a notification being shown on the device.

Why?

Because that would be highly insecure!

Anyone could be pushing to any device - and we definitely don't want that!

Therefore, as a developer, you have to register your app with Google and Apple and let them know that you plan on having push notifications as part of your app. You'll then get a unique key which you can use to send a "please deliver this message" request to Google's or Apple's push services and those services then go ahead and deliver the message to the devices (where the message is shown then).

So long story short - we need to do the following things in order to be able to deliver push notifications:

  1. Register our app with Google and Apple and let them know that we want to send push notifications

  2. Use the key / certificate that we get for sending messages

  3. Add code to our app to define what should happen if a user interacts with a received push notification

#

Adding Push Notifications to Android Flutter Apps

Let's add push notifications to an Android Flutter app.

Since Android is Google's mobile operating system, we need to use Google's push notification service to deliver the message (why? see above). This service is called FCM (Firebase Cloud Messaging). Firebase simply is a product offered by Google. Firebase offers more than just push notifications but the push service is part of it.

First of all, you need to sign up with Firebase and log into the Firebase Console.

There, you then need to add a new Android app.

Click the Android button in the Firebase web console

Simply follow the assistant and download the generated google-services.json file to your Flutter project. There, store it in the android/app folder.

Store the google-services.json file in the android/app folder

Next, edit your android/build.gradle file and add the following line to dependencies:

dependencies {
// ...
// Keep the other, existing entries!
// Add this line
classpath 'com.google.gms:google-services:4.3.2'
}

Also edit the android/app/build.gradle file to add this line of code at the bottom of the file:

apply plugin: 'com.google.gms.google-services'

That's it, this generally prepares your Android app to be able to receive (but not yet handle) push notifications.

The google-services.json basically is that unique key I mentioned earlier. It contains unique identification data which tells Android that your app is registered to receive push notifications.

Keep in mind that we did register it in the Firebase console. Firebase is a Google service and therefore Google is now aware of your app.

Of course just adding the google-services.json file to your project is not enough - it's not going to be parsed and interepreted by your app automatically.

Instead, we now need to add a new Flutter library to our project: The Firebase Messaging package.

To install it, add the following entry to your pubspec.yaml file:

firebase_messaging: ^6.0.16

(the version can differ, find the latest version

Thereafter, your IDE either picks it up automatically and installs it or you need to run

flutter packages get

Now we need to add some code to our Flutter app.

At some point, we need to initialize the messaging package and also ask the user for permission. This could be done in the main.dart file but you can do it anywhere (e.g. you could also do it on some screen that shows up after authentication).

import 'package:firebase_messaging/firebase_messaging.dart';
// other code ...
class _MyWidgetState extends State<MyWidget> {
@override
void initState() {
super.initState();
final fbm = FirebaseMessaging();
fbm.requestNotificationPermissions();
}
}

Once all of that is done, you can build your app and test it on an emulator or a real device.

Thereafter, you can try sending a message via the Firebase web push console.

Go to "Cloud Messaging" in your Firebase project console (you find it under "Grow") and click on "Send your first message".

Simply enter a title and a notification text and click on "Next".

In the "Target" part, simply choose "App" and then select your registered Android app in the dropdown.

Follow the above steps and select your app

Click "Next" again and keep "Now" as a scheduled time.

Click "Next" on last time (you don't need to add any data on that final screen) and select "Review" thereafter.

Once you did all of that, you can click "Publish" and after a few seconds, the message should show up on your device.

At the moment, we got no control over what happens when a user reacts to a push notification (e.g. when the notification gets clicked). We'll work on this in the later, after we added iOS push notifications. Of course you can jump right ahead if you don't plan on supporting iOS.

#

Adding Push Notifications to iOS Flutter Apps

I strongly recommend that you go through the Adding Push Notifications to Android Apps part first, since that knowledge will help a lot in this part as well.

Because there's one really cool thing: Even though we have to use "APNs" for push notifications that should be delivered to iOS devices, we can continue using "FCM" (the service we needed for Android).

Why?

Because "FCM" supports both Android and iOS!

For Android, it simply sends the messages itself, for iOS, it basically forwards your message to "APNs". So you can use one service for both and that of course helps a lot!

We still need to let Apple know about our intents though and we therefore still need to go through a couple of iOS-specific steps. But we will be using the "FCM" and also the Firebase Messaging Flutter package we used before.

So first of all, you should go back to your Firebase web console and add your iOS app as well.

For that, on the starting page of the console, click on "Add app" and then select the iOS icon.

Go through the wizard (only until "Download config file" though) and download the GoogleService-Info.plist file. Open your ios/Runner.xcworkspace file with XCode and then add the GoogleService-Info.plist file to the project.

Add the config file to your Runner project via Add Files to

Skip the rest of the wizard (i.e. don't go through the "Add Firebase SDK" step and the following steps).

We now need to let iOS know about the fact that our apps wants to use push notifications. For that, select "Runner" in XCode and turn on "Push Notifications" and "Background Modes" in the "Signing & Capabilities" tab.

Turn on Push Notifications and Background Modes in XCode

Thereafter, under "Background Modes", check "Remote notifications" and "Background fetch".

We're almost there, just a few steps left!

As mentioned before, "FCM" is going to forward our to-be-delivered messages to "APNs". Hence we also need to register our app with "APNs". Do that as described here. Skip the "Create the Provisioning Profile" step!

As part of the previous step, you'll get an "APNs" authentication key (a file you had to download in the last step).

This key file now needs to be uploaded to "FCM" so that this service is able to "talk to APNs". Upload it as described here.

And with that, we're done!

Make sure you added the Firebase messaging package to your Flutter app (also see the Android part of this article for more details).

Last but not least, just as with Android, we need to add some Flutter code to be prepared to receive messages (and to ask for permission). If you already followed the Android instructions from above, you already have the below code snippet:

import 'package:firebase_messaging/firebase_messaging.dart';
// other code ...
class _MyWidgetState extends State<MyWidget> {
@override
void initState() {
super.initState();
final fbm = FirebaseMessaging();
fbm.requestNotificationPermissions();
}
}

With all of that done, you can save everything and re-build your Flutter app to test this.

We can test push notifications with the same steps as for Android:

Go to "Cloud Messaging" in your Firebase project console (you find it under "Grow") and click on "Send your first message".

Simply enter a title and a notification text and click on "Next".

In the "Target" part, simply choose "App" and then select your registered iOS app in the dropdown.

Click "Next" again and keep "Now" as a scheduled time.

Click "Next" on last time (you don't need to add any data on that final screen) and select "Review" thereafter.

Once you did all of that, you can click "Publish" and after a few seconds, the message should show up on your device.

#

Reacting to Incoming Messages

By now, we can send push notifications to both Android and iOS Flutter apps. But user interaction with those incoming messages is not supported yet.

Typically, we want to open our app and maybe do something inside of that app (e.g. load a specific page) when we receive a message.

This can easily be implemented with help of the Firebase messaging package which we're alread using.

There, you can react to various events by adding this code:

import 'package:firebase_messaging/firebase_messaging.dart';
// other code ...
class _MyWidgetState extends State<MyWidget> {
@override
void initState() {
super.initState();
final fbm = FirebaseMessaging();
fbm.requestNotificationPermissions();
// highlight-start
fbm.configure(onMessage: (msg) {
print(msg);
return;
}, onLaunch: (msg) {
print(msg);
return;
}, onResume: (msg) {
print(msg);
return;
});
// highlight-end
}
}

You have three event handlers:

  • onMessage: Triggered if a message is received whilst the app is in foreground

  • onResume: Triggered if a message is received whilst the app is in background

  • onLaunch: Triggered if a message is received if the app was terminated

You find a detailed table here.

Now it's up to you what you want to do in those handlers. You could switch to a different route, show some alert or overlay to the user or do anything else you need to do.

#

Configuration Options

There's more which you can configure and do. I strongly recommend that you also have a detailed look at the Firebase messaging package docs for more information.

#

Next Steps

In this tutorial, we added push notifications such that you can directly send them via the Cloud Messaging web UI. Sometimes, that is exactly what you want (e.g. to deliver marketing messages to your users).

Sometimes, you also want to send out automated messages - for example in a chat app.

That's something I also show in my Flutter course. And in general, you find a detailed video guide on Flutter, realtime messaging, push notifications and much more in that course!

Recommended Courses