Webelight Solutions Blog: Insights on IT, Innovation, and Digital Trends

Firebase Push Notifications in Flutter: Android & iOS guide

Mahammadali Dodiya

JAN 24, 2025

Blog-hero

In this article, I will show you how to implement push notifications on Android and iOS, with support for and without flavours. Whether you are a beginner or an experienced developer, this guide for mastering Firebase Push Notifications will help you set up Firebase push notifications seamlessly in your Flutter project. Get ready to take your app to the next level with Firebase and Flutter push notifications, and go through my Firebase push notifications tutorial for Flutter. Don’t miss out— improve your mobile app development experience today!

 

Getting started on mastering Firebase push notifications! 

 

Firebase setup

a) First, create a new project (if you haven’t already) in Firebase by heading to the Firebase console and pressing "Add Project".

Firebase setup

b) Enter a project name and click "Continue".

Name of project

c) Then, click "Create Project".

 

How to integrate the Firebase project with the Android setup?

 

Follow the steps below to integrate the Firebase project with the Android app setup.

Click the Android icon on the project overview page:

Android setup

This will lead to a form. First, enter the Android package name. You can find this in your project directory→android→app→src→AndroidManifest.xml. On the second line, you’ll see your package name. Just copy and paste it into the form.

Optionally, you can choose a nickname for your app. If you leave this field empty, an auto-generated app name will be used.

Choose a name for your app

Click the Register app. This will take you to the next step.

Download the "google-services.json" file, drag and drop it into your project directory → android → app, and click next to continue.

Download config file

Add Firebase SDK:

1) Add the classPath of "google-services" in "build.gradle" android file.

Add the class Path of google services in build gradle android file

2) Add an apply plugin of google-services to your "build.gradle.app" file.

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

Now, your Android app should be connected to Firebase! This is how you integrate the Firebase project with the Android app setup.

 

Steps to Configure Firebase for Android with Flavors:

1) Configure Flavors in Flutter:

Ensure that you have correctly configured flavours in the Flutter project.

2) Create Flavor-wise Folders

a) In your Android project, navigate to "android/app/src/".
b) Create separate folders for each flavour, such as "dev" and "prod", under the "src" directory.

Create separate folders for each flavour under the src directory

Import the "google-services.json" file:

For each flavour, place the corresponding "google-services.json" file inside its respective folder ("dev" or "prod").

 

How to integrate the Firebase project with the IOS setup?

 

Requirements (for IOS) :

a) Apple developer account.
b) Mac device with Xcode installed.
c) iPhone or iPad (IOS simulators don’t receive Firebase notifications).

To integrate the Firebase project with the IOS setup of the app, follow the steps below:

a) Open your Firebase project console, click the gear icon in the upper left corner, and select "Project setting"

click the gear icon in the upper left corner and select Project setting
b) Select the IOS icon in the "Your apps" section.

Select the IOS icon in the Your apps section
c) Fill in the information.
d) iOS bundle ID: This is the bundle ID taken from your application. You can find them by going to Project Flutter, searching for keywords "PRODUCT_BUNDLE_IDENTIFIER" in file "ios/Runner.xcodeproj/project.pbxproj" 
e) Enter the app nickname (the name here is only used to distinguish between applications on Firebase, so you can set it arbitrarily).
f) You can omit this parameter "App Store ID".
g) Click "Register app"

Click on the button Download GoogleService info plist to download the file
h) Click on the button Download GoogleService-info.plist to download the file.
i) Always import the GoogleService-info.plist file from Xcode.

This is how you can integrate the Firebase project with the IOS setup, where you can integrate Firebase notifications. 
 

To set up Firebase for flavours in your project:

1) Create a Firebase Folder in Xcode.
2) Create subfolders for each flavour inside the Firebase folder, such as "dev" and "prod".
3) Add the corresponding flavour-specific "GoogleService-Info.plist" files to their respective folders:

a) "dev/GoogleService-Info.plist" for the development environment.
b) "prod/GoogleService-Info.plist" for the production environment.
c) Copy it to the ios directory of your project. If the "GoogleService-info.plist" file already exists, delete the old file and copy the new file.

Copy it to the ios directory of your project

If you are trying to run the app with flavours, ensure you have appropriately configured the Flutter flavours and added the necessary build script in Xcode to set up the Firebase environment based on the selected flavour.

1) Open Xcode and navigate to Runner > Build Phases.
2) Click on the + icon and select New Run Script Phase.
3) Provide a name for the script.

Name the script “Setup Firebase Environment Based on Flavour”.

Add the following build script inside the script section to ensure the Firebase configuration is loaded based on the selected flavour:

environment="default"

# Regex to extract the scheme name from the Build Configuration
# We have named our Build Configurations as Debug-dev, Debug-prod etc.
# Here, dev and prod are the scheme names. This kind of naming is required by 
Flutter for flavors to work.
# We are using the $CONFIGURATION variable available in the XCode build environment
to extract 
# the environment (or flavor)
# For eg.
# If CONFIGURATION="Debug-prod", then environment will get set to "prod".
if [[ $CONFIGURATION =~ -([^-]*)$ ]]; then
environment=${BASH_REMATCH[1]}
fi

echo $environment

# Name and path of the resource we're copying
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist
GOOGLESERVICE_INFO_FILE=${PROJECT_DIR}/Firebase/${environment}/${GOOGLESERVICE_INFO_PLIST}

# Make sure GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_FILE}"
if [ ! -f $GOOGLESERVICE_INFO_FILE ]
then
echo "No GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1
fi

# Get a reference to the destination location for the GoogleService-Info.plist
# This is the default location where Firebase init code expects to find 
GoogleServices-Info.plist file
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}"

# Copy over the prod GoogleService-Info.plist for Release builds
cp "${GOOGLESERVICE_INFO_FILE}" "${PLIST_DESTINATION}"

Add the following build script inside the script section to ensure the Firebase configuration is loaded based on the selected flavour

To set up Firebase without flavours in your project:

If you are not using flavours in your project, simply add the "GoogleService-Info.plist" file directly to the iOS > Runner folder in Xcode.

Add the Google Service Info plist file directly to the iOS Runner folder in Xcode

Open the "ios" folder of the project directory in Xcode. Drag and drop the file you downloaded into the "Runner" subfolder. When a dialog box appears, make sure the "Copy items if needed" of the "Destination" property are checked and "Runner" is selected in the "Add to targets" box. Then, click Finish.

Make sure the Copy items if needed of the Destination property are checked and Runner is selected in the Add to targets box

You can close Xcode now.

Add Firebase SDK and the initialization code.

Add Firebase SDK

Add the initialization code

Add the Below Line into your "AppDelegate.swift" file:

import FirebaseCore

 FirebaseApp.configure()

if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().delegate = self as? 
        UNUserNotificationCenterDelegate
 }

In addition, you must have an Apple developer account. Since Firebase Cloud Messaging integrates with the Apple Push Notification service, which only works with real devices, you’ll also need access to a physical iOS device to receive push notifications.

You can find a detailed, step-by-step guide to configuring the iOS app to receive push notifications in the official FireFlutter docs.

Before diving into the Flutter code, you must complete one more step in Firebase. Go to Project settings:

Project settings

Now, the Firebase setup and integration are complete. Let’s move on to the Flutter code.

 

Installing Flutter plugins for the Firebase project

 

We require the following Flutter plugins for this project:

a) firebase_core: Required to use any Firebase service with Flutter.
b) firebase_messaging: Used for receiving notifications in the app.
c) flutter_local_notifications: Used for displaying local notifications.

You can get these packages from pub.dev with their latest versions. Add them to the "pubspec.yaml" file of the Flutter project, where you want to integrate Firebase notifications.

Let’s create "firebase_messaging_services.dart" inside the service folder.

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import '../services/local_notification_service.dart';
import '../utils/utility_helper.dart';

class FirebaseMessagingService {
  FirebaseMessagingService._();

  static FirebaseMessagingService instance = FirebaseMessagingService._();

  late final FirebaseMessaging _messaging;

  Future<void> init() async {
    // 1. Initialize the Firebase app
    await Firebase.initializeApp();

    // 2. Instantiate Firebase Messaging
    _messaging = FirebaseMessaging.instance;

    // 3. On iOS, this helps to take the user permissions
    final NotificationSettings settings = await _messaging.requestPermission();

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      FirebaseMessaging.onMessage.listen((RemoteMessage message) {
        UtilityHelper.showLog('Called');
        if (message.notification != null) {
          LocalNotificationService.instance.showNotification(
            title: message.notification?.title,
            body: message.notification?.body,
          );
        }
      });

      FirebaseMessaging.onBackgroundMessage(
        _firebaseMessagingBackgroundHandler,
      );

      FirebaseMessaging.onMessageOpenedApp
          .listen((RemoteMessage message) async {
        UtilityHelper.showLog('Called');
        // final Map<String, dynamic>? userData = await
        // if (userData != null) {
        //   RoutesManager.handleNotificationNavigation(isReminder: false);
        // }
      });
    } else {
      UtilityHelper.showLog(
        'User declined or has not accepted permission',
      );
    }
  }

  Future<String?> getToken() async {
    final String? fcmToken = await _messaging.getToken();
    UtilityHelper.showLog(fcmToken ?? '');
    return fcmToken;
  }
}

Future<dynamic> _firebaseMessagingBackgroundHandler(
  RemoteMessage message,
) async {
  await Firebase.initializeApp();
  UtilityHelper.showLog(
    'Handling a background message: ${message.messageId}',
  );
}

Let’s create "local_notification_services.dart" inside the service folder.

import 'dart:io';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class LocalNotificationService {
  LocalNotificationService._();

  static final LocalNotificationService instance = LocalNotificationService._();

  FlutterLocalNotificationsPlugin? _flutterLocalNotificationsPlugin;

  Future<void> init() async {
    _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

    if (Platform.isIOS) {
      _requestIOSPermission();
    }

    await _intializePlateform();
  }

  void _requestIOSPermission() {
    _flutterLocalNotificationsPlugin
        ?.resolvePlatformSpecificImplementation<
            IOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );
  }

  Future<void> _intializePlateform() async {
    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    const DarwinInitializationSettings initializationSettingsIOS =
        DarwinInitializationSettings();

    const InitializationSettings initializationSettings =
        InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );

    await _flutterLocalNotificationsPlugin?.initialize(
      initializationSettings,
    );
  }

  Future<void> showNotification({
    String? title,
    String? body,
    String? payload,
  }) async {
    const AndroidNotificationDetails android = AndroidNotificationDetails(
      '1',
      'App Name',
      channelDescription: 'CHANNEL DESCRIPTION',
    );

    const DarwinNotificationDetails iOS = DarwinNotificationDetails();
    const NotificationDetails plateform = NotificationDetails(
      iOS: iOS,
      android: android,
    );
    await _flutterLocalNotificationsPlugin?.show(
      0,
      title,
      body,
      plateform,
      payload: payload,
    );
  }
}

All of the Push Notification steps have now been completed. You must initialise the local notification services and firebase messaging services in the main method of "main.dart" file.

main method of main dart file

 

Send a test message

 

There are two ways you can send a test message: via Firebase console or Postman (or any REST client you like).

1) Firebase console

The first method you can try is sending a test message from the Firebase console.

Now execute "flutter run" on the terminal and copy the token. Then navigate to the Firebase console -> Cloud Messaging and click "Send your first message". In the notification composer page, add the notification title and text.

notification composer page

And then click on Send Test Message, which will open the following modal.

Test on device

Then select test message. A notification will be sent to you.

select test message and a notification will be sent to you

2) Postman

The second method is to send a message request in Postman.

Steps:

a) Import FCM v1 Collection: You can import my public collection directly into Postman for convenience.
b) API Endpoint: Use the following POST endpoint for sending notifications:

https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send

Replace "YOUR_PROJECT_ID" with your Firebase project ID.

Headers:

Add the following headers to the request:

a) Authorization: "Bearer YOUR_ACCESS_TOKEN"
Generate the "ACCESS_TOKEN" using a service account.
b) Refer to the Firebase Admin SDK documentation for details on generating tokens.
c) Content-Type: "application/json"

Body:

Construct the request body in the following format:

{
  "message": {
    "token": "DEVICE_REGISTRATION_TOKEN",
    "notification": {
      "title": "Notification Title",
      "body": "Notification Body"
    },
    "data": {
      "key1": "value1",
      "key2": "value2"
    }
  }

a) Replace "DEVICE_REGISTRATION_TOKEN" with the recipient device's FCM token.
b) The "notification" field is for the title and body.
c) The "data" field can hold additional key-value pairs for custom payloads.

Sending Messages Using Topics


To send messages to multiple users, you can use topics. For example, two users can subscribe to a topic called "test".Using REST API or the Firebase admin SDK, you can send messages to that topic and all the subscribed users will receive a notification. You can subscribe to a topic.

messaging.subscribeToTopic("messaging");

main.dart hosted with ❤ by GitHub

You can also unsubscribe by executing.

messaging.unsubscribeFromTopic("messaging");

main.dart hosted with ❤ by GitHub

This was my comprehensive guide on how to implement push notifications on Android and iOS and mastering Firebase Push Notifications. I hope you enjoyed reading the Firebase push notifications tutorial for Flutter. If you have any questions or feedback, feel free to leave a comment below. I’d love to hear your thoughts and help you further with your Flutter projects!

At Webelight Solutions Pvt. Ltd., mobile app developers like me specialize in building cutting-edge, scalable mobile applications that drive results. Our mobile app solution exceeds expectations and can offer your business the competitive edge it deserves. 

Consult our experts for scalable cross-platform mobile app development services.

Mahammadali Dodiya

Flutter, Android and iOS Developer

Mahammadali Dodiya is an experienced flutter, Android, and iOS developer with strong leadership and problem-solving skills. He excels in designing solutions, code reviews, and tech work. Highly skilled in project delivery, management, and quality reviews, he has a track record of developing innovative and complex apps.

FAQ's

To set up Firebase push notifications in a Flutter app, you need to configure Firebase in your project, integrate Firebase SDKs, and set up platform-specific files for Android and iOS. This involves steps like adding the “google-services.json” file for Android or “GoogleService-Info.plist” for iOS, setting up Flutter plugins like firebase_messaging, and writing the necessary code to handle notifications.