Home / Flutter / Flutter Android Push Notifications with Firebase (FCM Setup Guide 2026)
android-push-notifications

Flutter Android Push Notifications with Firebase (FCM Setup Guide 2026)

Table of Contents

Push notifications are a crucial feature for mobile apps to engage users and deliver timely updates. Unlike iOS, Android implementation is more straightforward and doesn’t require complex certificate management. This guide provides a complete step-by-step walkthrough for enabling Android push notifications in your Flutter app using Firebase Cloud Messaging (FCM).

Good news: Android push notifications work on both emulators and real devices!

Prerequisites

Before starting, ensure you have:

  • A Flutter project with Android support (flutter create my_app)
  • Android Studio or VS Code installed
  • A Google account for Firebase
  • Basic knowledge of Flutter and Dart

Step 1: Create a Firebase Project

1.1 Set Up Firebase Console

  1. Go to the Firebase Console
  2. Click Add project or select an existing project
  3. Enter a project name (e.g., My Flutter App)
  4. Enable or disable Google Analytics (optional)
  5. Click Create Project

Your Firebase project is now ready!

Step 2: Configure Your Flutter Project

2.1 Install Firebase CLI

First, install the Firebase CLI and FlutterFire CLI:

# Install Firebase CLI
npm install -g firebase-tools

# Login to Firebase
firebase login

# Install FlutterFire CLI
dart pub global activate flutterfire_cli

2.2 Configure Firebase with FlutterFire

Run this command in your Flutter project root:

flutterfire configure

This command will:

  • Link your Flutter project to your Firebase project
  • Generate platform-specific configuration files
  • Create firebase_options.dart automatically

This is the easiest way to configure Firebase—no manual file downloads needed!

Step 3: Add Firebase to Your Android App

3.1 Update android/build.gradle

Open android/build.gradle and add:

buildscript {
    dependencies {
        // Add this line
        classpath 'com.google.gms:google-services:latest-version'
    }
}

3.2 Update android/app/build.gradle

Open android/app/build.gradle and add at the bottom of the file:

apply plugin: '[com.google.gms.google](<http://com.google.gms.google>)-services'

Also ensure your minSdkVersion is at least 21:

android {
    defaultConfig {
        minSdkVersion 21  // or higher
    }
}

Step 4: Install Required Dependencies

Add these packages to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.27.0
  firebase_messaging: ^14.7.0
  flutter_local_notifications: ^16.3.0

Run:

flutter pub get

Step 5: Request Notification Permissions (Android 13+)

Starting with Android 13 (API level 33), you need to request runtime notification permissions.

5.1 Update AndroidManifest.xml

Add this permission in android/app/src/main/AndroidManifest.xml:

<manifest>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="[android.permission.POST](<http://android.permission.POST>)_NOTIFICATIONS"/>
    
    <application>
        <!-- Your app code -->
    </application>
</manifest>

5.2 Request Permission in Dart

import 'package:firebase_messaging/firebase_messaging.dart';

Future<void> requestNotificationPermission() async {
  FirebaseMessaging messaging = FirebaseMessaging.instance;

  NotificationSettings settings = await messaging.requestPermission(
    alert: true,
    badge: true,
    sound: true,
    provisional: false,
  );

  print('User granted permission: ${settings.authorizationStatus}');
}

Step 6: Initialize Firebase and Request FCM Token

6.1 Initialize Firebase in main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';

// Top-level background message handler
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  print('Handling a background message: ${message.messageId}');
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize Firebase
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  
  // Set background message handler
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  
  runApp(MyApp());
}

6.2 Get FCM Token

Future<String?> getFCMToken() async {
  FirebaseMessaging messaging = FirebaseMessaging.instance;
  String? token = await messaging.getToken();
  
  print('FCM Token: $token');
  return token;
}

Save this token to your backend—you’ll need it to send targeted notifications.

Step 7: Handle Incoming Notifications

Firebase provides three states for handling notifications:

7.1 Foreground Messages

void setupForegroundNotificationHandler() {
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print('Received foreground message: ${message.notification?.title}');
    
    // Show notification using flutter_local_notifications
    if (message.notification != null) {
      _showLocalNotification(message);
    }
  });
}

7.2 Background/Terminated App Messages

void setupBackgroundNotificationHandler() {
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print('Notification opened app: ${message.notification?.title}');
    
    // Navigate to specific screen based on notification data
    if ([message.data](<http://message.data>)['screen'] != null) {
      // Navigate to screen
    }
  });
}

7.3 Show Local Notifications (Foreground)

import 'package:flutter_local_notifications/flutter_local_notifications.dart';

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

Future<void> initializeLocalNotifications() async {
  const AndroidInitializationSettings androidSettings =
      AndroidInitializationSettings('@mipmap/ic_launcher');
  
  const InitializationSettings settings = InitializationSettings(
    android: androidSettings,
  );
  
  await flutterLocalNotificationsPlugin.initialize(settings);
}

Future<void> _showLocalNotification(RemoteMessage message) async {
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'default_channel',
    'Default Channel',
    channelDescription: 'Default notification channel',
    importance: Importance.high,
    priority: Priority.high,
  );
  
  const NotificationDetails notificationDetails = NotificationDetails(
    android: androidDetails,
  );
  
  await [flutterLocalNotificationsPlugin.show](<http://flutterLocalNotificationsPlugin.show>)(
    message.hashCode,
    message.notification?.title,
    message.notification?.body,
    notificationDetails,
  );
}

Step 8: Send Test Notifications

Option 1: Firebase Console

  1. Go to Firebase Console → Cloud Messaging
  2. Click Send your first message
  3. Enter a notification title and text
  4. Click Send test message
  5. Paste your FCM token and click Test

Option 2: Using cURL

curl -X POST <https://fcm.googleapis.com/fcm/send> \\
  -H "Authorization: key=YOUR_SERVER_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
    "to": "YOUR_FCM_TOKEN",
    "notification": {
      "title": "Hello from Firebase!",
      "body": "This is a test notification"
    }
  }'

Find your server key in Firebase Console → Project Settings → Cloud Messaging → Server Key

Step 9: Troubleshooting Common Issues

IssueCauseSolution
FCM token is nullFirebase not initialized or Google Play Services missingEnsure Firebase is initialized and test on a device with Play Services
Notifications not showing in foregroundMissing local notification implementationUse flutter_local_notifications to display foreground messages
Background notifications not workingMissing background handlerAdd FirebaseMessaging.onBackgroundMessage() before runApp()
MissingPluginExceptionHot reload issueStop the app completely and rebuild with flutter run
Gradle build failsVersion conflicts or missing Google Services pluginCheck build.gradle files and ensure google-services plugin is applied

Tips and Best Practices for Push Notifications

  • Test on real devices: While emulators work, real devices provide the most accurate testing environment
  • Handle all notification states: Implement handlers for foreground, background, and terminated states
  • Use notification channels: Android 8.0+ requires notification channels for better user control
  • Store FCM tokens: Save tokens to your backend to send targeted notifications
  • Handle token refresh: Listen to token refresh events with onTokenRefresh
  • Add notification icons: Create custom notification icons in android/app/src/main/res/drawable/
  • Use data-only messages: For silent updates, use data-only payloads without notification field
  • Test different scenarios: Test with app in foreground, background, and terminated states

Conclusion

Setting up Android push notifications in Flutter is straightforward with Firebase Cloud Messaging. Unlike iOS, Android doesn’t require complex certificate management, making the implementation process much simpler. By following this guide, you’ve learned how to:

  • Configure Firebase for your Flutter Android app
  • Handle notifications in different app states
  • Display foreground notifications
  • Test and troubleshoot common issues

With push notifications properly implemented, your app can now engage users effectively with timely updates and important information.

Pro tip: Combine push notifications with deep linking to navigate users to specific screens when they tap notifications!

Leave a Comment