Introduction
Push notifications bridge the gap between your app and users, delivering timely updates, personalized offers, and critical alerts even when your app isn’t open. Firebase Cloud Messaging (FCM) offers a free, reliable, and cross-platform solution to implement push notifications on Android, iOS, and web. In this guide, you’ll learn how to set up an FCM project, integrate FCM SDKs into your mobile apps, send messages via the Firebase Console and programmatically, and adopt best practices for security and user experience. By the end, you’ll be equipped to deliver engaging, real-time notifications that drive retention and engagement.

Understanding Push Notifications and FCM
Push notifications are messages sent from a server to devices that have your app installed. They’re ideal for:
- Transactional alerts: Order updates, verification codes.
- Engagement boosts: Promotional offers, content recommendations.
- Time-sensitive reminders: Event countdowns, news alerts.
Firebase Cloud Messaging provides:
- Cross-platform delivery: Android, iOS, web.
- Scalable infrastructure: Google-backed, handles millions of devices.
- Flexible APIs: Send via console, HTTP v1 API, Admin SDKs.
- Advanced routing: Topics, device groups, and user segments.
Expert Insight: FCM decouples your app from push services (APNs for iOS, Google’s FCM for Android), letting you write one backend and deliver everywhere.
Prerequisites and Setup
Firebase Project Setup
- Create a Firebase Project:
- Go to Firebase Console and click Add project.
- Follow prompts, enable Google Analytics if desired.
- Register Your App:
- In Project settings, under Your apps, click Add app and choose Android or iOS.
- For Android: supply your package name (e.g.,
com.example.myapp
). - For iOS: supply your bundle ID and upload
GoogleService-Info.plist
.
- Download Configuration Files:
- Android:
google-services.json
→ place inapp/
directory. - iOS:
GoogleService-Info.plist
→ add to Xcode project.
- Android:
Installing Firebase SDK
- Android (Gradle) gradleCopyEdit
// In project-level build.gradle buildscript { dependencies { classpath 'com.google.gms:google-services:4.3.15' } } // In app-level build.gradle apply plugin: 'com.android.application' apply plugin: 'com.google.gms.google-services' dependencies { implementation 'com.google.firebase:firebase-messaging:23.1.2' }
- iOS (CocoaPods) rubyCopyEdit
# Podfile platform :ios, '12.0' pod 'Firebase/Messaging'
bashCopyEditcd ios && pod install && cd ..
Pro Tip: Always use the latest SDK versions from the Firebase Release Notes.
Integrating FCM in Android App

Adding Gradle Dependencies
Make sure your build.gradle
files include the Google Services plugin and FCM library as shown above.
Configuring AndroidManifest.xml
Add the FirebaseMessagingService
and permissions:
xmlCopyEdit<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application ...>
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
Retrieving FCM Token
Your app needs a device token to receive messages:
javaCopyEditFirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(task -> {
if (!task.isSuccessful()) return;
String token = task.getResult();
Log.d("FCM", "Device token: " + token);
// Send token to your backend
});
Handling Incoming Messages
Extend FirebaseMessagingService
and override handlers:
javaCopyEditpublic class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage message) {
// Handle data payload
Map<String, String> data = message.getData();
// Build and display a notification
}
@Override
public void onNewToken(String token) {
// Send updated token to your server
}
}
Example: Use
NotificationCompat.Builder
to craft rich notifications with custom icons, actions, and deep links.
Integrating FCM in iOS App
Requesting Notification Permissions
In your AppDelegate.swift
:
swiftCopyEditimport Firebase
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
print("Permission granted: \(granted)")
}
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
return true
}
// Receive APNs token and pass to FCM
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
}
Handling FCM Token Updates and Messages
Conform to MessagingDelegate
and UNUserNotificationCenterDelegate
:
swiftCopyEditextension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("FCM token: \(fcmToken ?? "")")
// Send token to your backend
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
// Foreground notifications
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .sound])
}
// User tapped notification
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
// Handle navigation
completionHandler()
}
}
Expert Insight: Use APNs authentication keys instead of certificates for streamlined setup in the Firebase Console.
Sending Notifications from Server
Using Firebase Console
- Navigate to Cloud Messaging in your project.
- Click Send your first message, craft title/body, select target (topic, token, user segment).
- Schedule or send immediately.
- Monitor delivery reports in the console.
Sending Programmatic Notifications
Use the FCM HTTP v1 API for production. Example Node.js snippet:

javascriptCopyEditconst {getMessaging} = require('firebase-admin/messaging');
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault()
});
const message = {
token: deviceToken,
notification: {
title: 'New Offer',
body: 'Get 20% off your next order!'
},
data: {
offerId: 'OFF123'
}
};
getMessaging().send(message)
.then(response => console.log('Sent message:', response))
.catch(error => console.error('Error sending message:', error));
Best Practice: Secure your server key and restrict API access via Firebase Console’s API key restrictions.
Advanced Features and Best Practices
- Topic Messaging: Broadcast to segments: javascriptCopyEdit
admin.messaging().subscribeToTopic([token], 'news-updates');
- Device Groups: Group multiple tokens under one notification key.
- Data-only Messages: Use for silent background updates.
- Security:
- Rotate server keys regularly.
- Use OAuth2 for HTTP v1 API instead of legacy keys.
- Testing & Debugging:
- Use Postman or
curl
to test endpoints. - Check Android Logcat and Xcode console for errors.
- Use Postman or
- UX Considerations:
- Respect user preferences; allow opt-out.
- Design notifications with clear title, concise body, and meaningful action buttons.
- Throttle messages to avoid spamming.

Conclusion
Implementing push notifications with Firebase Cloud Messaging empowers you to deliver engaging, real-time updates across Android and iOS with a single backend. By setting up your Firebase project, integrating FCM SDKs, handling tokens and message callbacks, and adopting best practices for security and user experience, you’ll boost user retention and satisfaction. Whether you’re sending promotional offers, event reminders, or data sync triggers, FCM’s robust infrastructure ensures reliable delivery and flexible targeting. Start sending your first push today—and watch engagement soar.