Notifications in Flutter

I used Firebase Messaging to implement notifications in Flutter. Despite the many documentations around, it took me a while to get my first notification in.

Features

With Firebase Messaging, you can send messages to:

  • a single device, identified by an FCM token.
  • topics: typically for several devices of one same user.
  • groups of devices: large number of devices, but latency might be bad.

The behavior when receiving a message is also well thought:

  • if the app is on the foreground, a callback is called. No notification is displayed.
  • if the app is in the background or closed, a notification is displayed. If the user taps on it, the app is launched, and a callback is called.

Set up

Set up the app

Set up the app according to https://pub.dev/packages/firebase_messaging. If you're trying to set it up in iOS, this article might be useful too. Once it is set up, print out the FCM token like so:

import 'package:firebase_messaging/firebase_messaging.dart';

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

_firebaseMessaging.getToken().then((token) {
  print("FCM token: $token");
});

Also add a listener to the various events from Firebase Messaging

_firebaseMessaging.configure(onMessage: (message) {
  print('onMessage $message');
}, onLaunch: (message) {
  print('onLaunch $message');
}, onResume: (message) {
  print('onResume $message');
});

Then head over to the Firebase Console, use that token to create a message and send it. And I now see the notification in Android Studio:

Sending to a group of devices

Sending to a single device is great, but what about if I installed the same app on several devices? I'd want each device to receive the message. Instead of manually keeping track of FCM tokens and storing them somewhere in my database, we use topics. I subscribe to a topic whose name is my user id so that it is unique to me:

final FirebaseAuth _auth;
...
_auth.onAuthStateChanged.listen((user) {
  setState(() {
    signedIn = user != null;
  });
  if (user != null) {
    _firebaseMessaging.subscribeToTopic(user.uid);
  }
});

Send messages on updates to Firestore

It works like so: a Firebase Cloud Function listens to changes in the Firestore database. Depending on what changed, it decides who to notify and sends the message.

To cover this more in-depth, I wrote about it in this separate article.