Firebase Cloud Message (FCM) with Flutter 3.0
Tags: flutter, firebase, dart, mobile
Published: 2023-07-17 18:51:38

When you're looking for notification systems, most of the time you want something fast to respond and implement. Incorporating a reliable and efficient messaging platform is essential for a business.
This article explores the integration of Firebase Cloud Messaging (FCM) with the latest Flutter version, offering developers a fast and effortless solution to implement good push notification capabilities in their Android applications. 

## Before we continue

- Ensure that you have the [Firebase CLI](https://firebase.google.com/docs/cli?hl=pt-br#windows) installed on your machine. This requires NodeJS v16+ and a Firebase account.
- You must have a basic Flutter app repository cloned to your machine.
- Proceed by creating a `firebase.json` file. To do this, type `firebase init` in your terminal while inside the root folder of your project.

## Integrating Firebase into your Flutter project.

To ensure that the app is configured correctly with Firebase, you need to use the [Flutterfire CLI](https://firebase.google.com/docs/flutter/setup?hl=pt-br&platform=android). First, select or create a project, and Flutterfire will create an app associated with each platform inside your Firebase project. A prompt will appear like this:

```bash
$flutter_mobile_client>flutterfire configure
i Found 4 Firebase projects.
✔ Select a Firebase project to configure your Flutter application with · fcm-push-notification (mkp-push-notification)
? Which platforms should your configuration support (use arrow keys & space to select)? ›
✔ android
✔ ios
✔ macos
✔ web
```

After that, you can go to your Firebase account, select your project, and see the list of apps that you accepted in the prompt.

To proceed, you need to install the missing dependency from Firebase: `firebase_core`. Type `flutter pub add firebase_core` to install it.

In your `lib/main.dart` file, import the following files:

```tsx
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
```

To initialize your Firebase application, you must import the object from `firebase_options.dart`.

```dart
await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);
```

You can also install plugins to utilize most of the features from Firebase. A list of available plugins can be found [here](https://firebase.google.com/docs/flutter/setup?platform=android#available-plugins).

### Configuring Your Android App

After running `flutterfire configure`, a file named `google-services.json` will be generated at the module, also known as the *app-level*, of your Android application. The app-level path example is **`<project>/<app-module>/build.gradle`**. To make it accessible to the Firebase SDK (which you will be using later), you need the [Google services Gradle plugin](https://developers.google.com/android/guides/google-services-plugin).

First, go to `build.gradle` at your app-level and add:

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

Then, go to your `build.gradle` file at the root-level (**`<project>/build.gradle`**) and add:

```groovy
plugins {
...list of plugins

// Add the dependency for the Google services Gradle plugin
// the plugin version may change by the time of this post
  id 'com.google.gms.google-services' version '4.3.15' apply false
}
```

Now you need to add the Firebase SDK to your app. We will be using the [Firebase Android BoM](https://firebase.google.com/docs/android/learn-more#bom) dependency for this guide. Again, in your app module, add the following lines inside the `build.gradle` file:

```groovy
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:32.2.0"))

// Add the dependencies for the Firebase Cloud Messaging and Analytics (if you're using one of them) libraries.
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation("com.google.firebase:firebase-messaging")
```

<aside>
💡 Note: All modifications made to the `build.gradle` file at the root and app level should have their Java classpath/configuration synchronized. You can find more information about BoM and sync erros [here](https://firebase.google.com/docs/cloud-messaging/android/first-message#add_firebase_sdks_to_your_app).
</aside>

Lastly, now you only need to install `firebase_messaging` library to be able to manage your app’s background notifications. Type `flutter pub add firebase_messaging` at your terminal and import to your `main.dart` file or to some specific file to handle background notifications.

### (Optional) Sending a Test Message to a Specific Device

For testing on a target device, you can follow [this guide](https://firebase.google.com/docs/cloud-messaging/flutter/first-message) for more details.

To begin, invoke the FirebaseMessaging object and retrieve the token. You can print the token result on your console and then paste the token into Firebase. To do this, select your project, navigate to the "Messaging" tab, and select or create your campaign. A button to send a test message will appear. Paste the `fcmToken` value into the designated field.

```dart
final fcmToken = await FirebaseMessaging.instance.getToken();
```

## Sending your first notification message with FCM

For this step you need to have your app installed on your device then go to Firebase, select your project, search for “Messaging” tab and select or create your campaign. There is no secret in this part. It is as easy as it seems.

<aside>
💡 Note: If your app doesn’t have an `onBackgroundMessage` handler function, neither the test message nor the campaign will work. The next chapter will solve the issue.
</aside>

## Create a handler for background notifications from Firebase

At the top of your application, preferably under the `Firebase.initializeApp`, you should type the following:

```dart
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
```

The `_firebaseMessagingBackgroundHandler` is simply a function that will guarantee that all background messages are being received.

```dart
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {

  print("Handling a background message: ${message.messageId}");
}
```

You should also verify if you have enabled `uses-permission` for Android in the `AndroidManifest.xml` file:

```groovy
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
```

<aside>
💡 For more information about the configuration and how to set up background notifications for iOS, MacOS, and Web then [this guide](https://firebase.flutter.dev/docs/messaging/usage/#receiving-messages) will help you out.
</aside>

That’s all, folks!