A clean, minimal Android application demonstrating Firebase Cloud Messaging (FCM) integration with Jetpack Compose and Kotlin.
This sample demonstrates the core functionality of Firebase Cloud Messaging:
- π± Topic Subscription: Subscribe your device to FCM topics with a single button tap
- π Token Management: Retrieve and log your device's unique FCM registration token
- π¬ Push Notifications: Receive and handle cloud messages in real-time
- π¨ Modern UI: Clean interface built with Jetpack Compose
| Feature | Description |
|---|---|
| Subscribe to Topic | One-tap subscription to the "general" topic for group messaging |
| Print FCM Token | Instantly retrieve and log your device token for testing |
| Background Notifications | Automatic notification handling when app is in background |
| Foreground Messages | Custom message handling when app is active |
Before getting started, make sure you have:
- β Android Studio Hedgehog (2023.1.1) or newer
- β JDK 11 or higher
- β Android device or emulator (API 21+)
- β Google account for Firebase Console
- β Basic understanding of Kotlin and Jetpack Compose
- Navigate to Firebase Console
- Click "Add project" or select existing one
- Follow the setup wizard (Google Analytics is optional)
- Click the Android icon in your Firebase project
- Provide the following:
- Package name: Must match your app's package (e.g.,
com.example.fcmsample) - App nickname: Optional friendly name
- Package name: Must match your app's package (e.g.,
- Click "Register app"
-
Download the
google-services.jsonconfiguration file -
Place it in your project's
app/directory (NOT insrc/)YourProject/ βββ app/ β βββ google-services.json β HERE β βββ build.gradle.kts β βββ src/ -
Important: Add to
.gitignoreto keep credentials secure:# Firebase google-services.json
Cloud Messaging is enabled by default for new Firebase projects. You can verify:
- Navigate to Build β Cloud Messaging in Firebase Console
- Note your Server Key (found in Project Settings β Cloud Messaging)
Add the Google Services plugin to your project-level build file:
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.compose) apply false
id("com.google.gms.google-services") version "4.4.4" apply false // ADD this
}Apply the plugin and add Firebase dependencies:
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services") // Add this
}
dependencies {
// Firebase BOM
implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
implementation("com.google.firebase:firebase-messaging-ktx")
// Compose & Coroutines (versions in your project)
// ... other dependencies
}Add required permissions and FCM service declaration:
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Inside <application> tag -->
<service
android:name=".FCMService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>- Sync Gradle files
- Clean and rebuild project
- Verify no build errors
β οΈ Common Issue: If sync fails, ensuregoogle-services.jsonis in the correct location
| Library | Purpose |
|---|---|
firebase-messaging-ktx |
FCM SDK for receiving push notifications |
compose-bom |
Jetpack Compose Bill of Materials |
material3 |
Material Design 3 components for UI |
kotlinx-coroutines-play-services |
Coroutines support for Firebase APIs |
The app consists of three main components:
- Handles incoming push notifications
- Manages token refresh events
- Logs message payloads for debugging
- Displays two primary action buttons
- Manages notification permissions (Android 13+)
- Handles user interactions with coroutines
- Subscribe Button: Calls
FirebaseMessaging.getInstance().subscribeToTopic("general") - Print Token Button: Retrieves token via
FirebaseMessaging.getInstance().token - Shows status messages for user feedback
- β
Ensure
google-services.jsonis inapp/directory - β Sync Gradle files
- β Build and run on a physical device (recommended) or emulator
- β Grant notification permission when prompted (Android 13+)
- Subscribes your device to the "general" FCM topic
- Allows sending group notifications to all subscribed devices
- Success confirmation shown on screen
- Check Logcat filter
FCM_SUBSCRIBEfor detailed logs
- Retrieves your device's unique FCM registration token
- Token is logged to Logcat (filter:
FCM_TOKEN) - Use this token for sending targeted notifications to specific devices
- Token format:
eXXXXXX:APA91bXXXXXXX...
- Open Firebase Console β Engage β Cloud Messaging
- Click "Send your first message" or "New campaign"
- Fill in notification details:
- Title: "Test Notification"
- Text: "Hello from Firebase!"
- Choose target:
- Topic:
general(if you subscribed) - Single device: Paste the FCM token from logs
- Topic:
- Click Review β Publish
Send to specific device:
curl -X POST https://fcm.googleapis.com/fcm/send \
-H "Authorization: key=YOUR_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "DEVICE_TOKEN_HERE",
"notification": {
"title": "Test Title",
"body": "Test message from cURL"
}
}'Send to topic subscribers:
curl -X POST https://fcm.googleapis.com/fcm/send \
-H "Authorization: key=YOUR_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "/topics/general",
"notification": {
"title": "Topic Notification",
"body": "Message to all subscribers"
}
}'π‘ Find your Server Key: Firebase Console β Project Settings β Cloud Messaging β Server key
Issue: FCM token is null or not appearing in logs
Solutions:
- β
Verify
google-services.jsonis inapp/directory (notsrc/) - β Confirm package name matches Firebase Console registration
- β Check internet connectivity
- β
Clean and rebuild:
./gradlew clean build - β Invalidate caches: File β Invalidate Caches β Restart
Issue: Notifications aren't showing up
Solutions:
- β Grant notification permission (Settings β Apps β Your App β Notifications)
- β Disable battery optimization for the app
- β Test on a physical device (emulators can be unreliable)
- β Verify correct Server Key and device token/topic
- β Check Logcat for error messages
Issue: Gradle sync or build failures
Solutions:
- β
Ensure Google Services plugin is applied:
id("com.google.gms.google-services") - β
Validate
google-services.jsonformat (must be valid JSON) - β Check internet connection for dependency downloads
- β Update to latest Firebase BOM version
- β
Clear Gradle cache:
./gradlew clean
Issue: App crashes immediately after opening
Solutions:
- β
Check for missing
FCMServicedeclaration in AndroidManifest - β Verify all required permissions are declared
- β Review Logcat stack trace for specific errors
- β
Ensure FCM service extends
FirebaseMessagingService
π‘ Debug Tip: Always check Logcat with package name filter for detailed error messages
- π« Never commit
google-services.jsonto public repositories - π Add to
.gitignore:google-services.json - π Store server keys as environment variables in production
- π Implement token refresh logic in
onNewToken() - β Validate notification payloads server-side
- π Use HTTPS for all server communications
- Use lowercase with hyphens:
news-updates,sports-alerts - Avoid spaces and special characters
- Keep names descriptive and meaningful
- Implement backend service for token management
- Store tokens securely in database
- Handle
onNewToken()for token refresh - Add notification channels (Android 8.0+)
- Implement analytics for delivery tracking
- Test on multiple Android versions
- Configure proper notification icons and colors
- Firebase Cloud Messaging Docs
- Android FCM Client Guide
- Jetpack Compose Documentation
- FCM HTTP v1 API
Contributions are welcome! Feel free to:
- π Report bugs via Issues
- β¨ Suggest new features
- π§ Submit pull requests
- π Improve documentation
This project is available for educational purposes. Feel free to use and modify.
Need Help? Check Stack Overflow or Firebase Community
Made with β€οΈ using Kotlin & Jetpack Compose