0Pricing
Android Academy · Lesson

Push Notifications

Send push notifications via Firebase Cloud Messaging. Set up FCM, create notification channels, build notifications with actions, and handle foreground vs background delivery.

Push Notifications is a free Android Academy lesson on CoddyKit — lesson 4 of 6. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, one of 6 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Are Push Notifications?

Push notifications let your server send messages to users even when the app is not in the foreground. Common uses:

  • New message alerts
  • Order status updates
  • Breaking news
  • Reminders and promotions

On Android, Firebase Cloud Messaging (FCM) is the standard push delivery service.

FCM Overview

Firebase Cloud Messaging (FCM) flow:

  1. App registers with FCM on first launch → receives a device token
  2. App sends the token to your server
  3. When you want to push, your server sends a message to FCM
  4. FCM delivers it to the device

FCM is free, reliable, and works even when the app is killed.

Adding Firebase to the Project

Steps to add Firebase:

  1. Go to Firebase Console → Add project → Add Android app
  2. Register your app with the package name
  3. Download google-services.json and place it in app/
  4. Add plugins and dependencies
// project/build.gradle:
buildscript {
    dependencies { classpath 'com.google.gms:google-services:4.4.1' }
}

// app/build.gradle:
plugins { id 'com.google.gms.google-services' }

dependencies {
    implementation platform('com.google.firebase:firebase-bom:32.7.4')
    implementation 'com.google.firebase:firebase-messaging-ktx'
}

FCM Permission (Android 13+)

Starting with Android 13 (API 33), you must request the POST_NOTIFICATIONS permission at runtime — just like a dangerous permission:

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

// In Activity (Android 13+):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}

FirebaseMessagingService

Create a service that handles incoming FCM messages and token refreshes:

class MyFirebaseService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        // Send token to your backend to enable push delivery
        sendTokenToServer(token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
        val title = message.notification?.title ?: "New Message"
        val body  = message.notification?.body  ?: ""
        showNotification(title, body)
    }
}

Register Service in Manifest

Declare the service in AndroidManifest.xml:

<service
    android:name=".MyFirebaseService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Notification Channels (Android 8+)

Since Android 8 (Oreo), notifications must be assigned to a channel. Users can control sound, vibration, and importance per channel:

fun createNotificationChannel(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel(
            "messages_channel",           // channel ID
            "Messages",                   // user-visible name
            NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "Incoming message notifications"
            enableVibration(true)
        }
        val manager = context.getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(channel)
    }
}

Building & Showing a Notification

Use NotificationCompat.Builder for compatibility across Android versions:

fun showNotification(context: Context, title: String, body: String) {
    val intent = Intent(context, MainActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        context, 0, intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

    val notification = NotificationCompat.Builder(context, "messages_channel")
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle(title)
        .setContentText(body)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setAutoCancel(true)             // dismiss on tap
        .setContentIntent(pendingIntent) // open app on tap
        .build()

    NotificationManagerCompat.from(context)
        .notify(System.currentTimeMillis().toInt(), notification)
}

Notification with Actions

Add action buttons to notifications so users can act without opening the app:

val replyIntent = Intent(context, ReplyReceiver::class.java)
val replyPending = PendingIntent.getBroadcast(
    context, 1, replyIntent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

val notification = NotificationCompat.Builder(context, "messages_channel")
    .setSmallIcon(R.drawable.ic_notification)
    .setContentTitle("New message from Alice")
    .setContentText("Hey, are you coming?")
    .addAction(R.drawable.ic_reply, "Reply", replyPending)
    .addAction(R.drawable.ic_dismiss, "Dismiss", null)
    .build()

Foreground vs Background Handling

FCM behaves differently depending on app state:

  • App in foregroundonMessageReceived() is called; you build and show the notification yourself
  • App in background/killed — FCM automatically shows the notification from the notification payload; onMessageReceived is NOT called

Put extra data in the data payload (not notification) to always receive it in onMessageReceived.

Getting the FCM Token

Retrieve the current FCM token to send to your server:

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w("FCM", "Fetching token failed", task.exception)
        return@addOnCompleteListener
    }
    val token = task.result
    Log.d("FCM", "Token: $token")
    // Send token to your server
    sendTokenToServer(token)
}

Quick Check

What happens when your app is in the background and FCM delivers a message with a 'notification' payload?

Recap: Push Notifications

Push notifications with FCM on Android:

  • Add Firebase, google-services.json, and firebase-messaging-ktx
  • Request POST_NOTIFICATIONS on Android 13+
  • Create FirebaseMessagingServiceonNewToken + onMessageReceived
  • Create a NotificationChannel for Android 8+
  • Build notifications with NotificationCompat.Builder
  • Use data payload to always receive in onMessageReceived

Next: schedule background work with WorkManager.

Frequently asked questions

Is the “Push Notifications” lesson free?

Yes — the full text of “Push Notifications” is free to read here on the web, and the Android Academy course includes 6 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Android Academy course, upgrade to CoddyKit PRO.

What will I learn in “Push Notifications”?

Send push notifications via Firebase Cloud Messaging. Set up FCM, create notification channels, build notifications with actions, and handle foreground vs background delivery. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Android Academy?

No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 6, so you can start here or from the beginning and move at your own pace.

How long does the “Push Notifications” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Android Academy lesson?

Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Retrofit & REST APIs
  2. Loading Images with Coil
  3. Error Handling & UX
  4. Push Notifications
  5. WorkManager & Background Tasks
  6. Publishing to Play Store
← Back to Android Academy