Firebase Cloud Messaging (FCM), a Google service, enables developers to send push notifications to devices using Android, iOS, and web platforms. Leveraging Google Cloud Messaging (GCM) for its core messaging functionality, FCM enhances this with features like targeting specific groups of devices and confirming message delivery. It supports sending messages to offline devices and allows for the inclusion of custom data in messages.

In this step-by-step guide, we're going to show you how to easily integrate FCM in your Android application:

NOTE (Before running your app on device):

  1. Make sure your Android devices have at least Android 4.4 and the Google Play Store app installed.
  2. If you are using an emulator, set it to run Android 4.4 with Google APIs.

STEP 1 : Create Firebase Project and Register your App

Before you can add Firebase to your Android app, you need to create a Firebase project to connect to your Android app.

  1. In the  Firebase console, click  Add project.
  2. To add Firebase resources to an  existing  Google Cloud project, enter its project name or select it from the dropdown menu.
  3. To create a new project, enter the desired project name. You can also optionally edit the project ID displayed below the project name.
  4. Click  Create project  (or  Add Firebase, if you're using an existing Google Cloud project).

To use Firebase in your Android app, you need to register your app with your Firebase project. Registering your app is often called "adding" your app to your project.

  1. Go to the  Firebase console.
  2. In the center of the project overview page, click the  Android  icon (plat_android) or  Add app  to launch the setup workflow.
  3. Enter your app's package name in the  Android package name  field.
  4. Click  Register app.

NOTE : It is (Optional) to enter other app information: App nickname and Debug signing certificate SHA-1 in the steps above.

STEP 2 : Configure your App with Firebase (FCM)

Download and then add the Firebase Android configuration file (google-services.json) to your app:

  1. Click  Download google-services.json  to obtain your Firebase Android config file.
  2. Move your config file into the  module (app-level)  root directory of your app.

NOTE : To make the values in your google-services.json config file accessible to Firebase SDKs, you need the Google services Gradle plugin (google-services).

  1. In your root-level (project-level) Gradle file (<project>/build.gradle.kts or <project>/build.gradle), add the Google services plugin as a dependency:
plugins { id("com.android.application") version "7.3.0" apply false // ... 
**// Add the dependency for the Google services Gradle plugin**
id("com.google.gms.google-services") version "4.4.0" apply false
}
  1. In your module (app-level) Gradle file (usually <project>/<app-module>/build.gradle.kts or <project>/<app-module>/build.gradle), add the Google services plugin:
plugins { id("com.android.application") 
 **// Add the Google services Gradle**
 plugin id("com.google.gms.google-services")
}

  1. In your module (app-level) Gradle file (usually <project>/<app-module>/build.gradle.kts or <project>/<app-module>/build.gradle), add the dependencies for the Firebase products that you want to use in your app. We recommend using the Firebase Android BoM to control library versioning.
dependencies 
{ 
**// Import the Firebase BoM implementation(platform("com.google.firebase:firebase-bom:32.7.1"))** // When using the BoM, you don't specify versions in Firebase library dependencies 
**// Add the dependency for the Firebase SDK for Firebase Cloud Messaging(FCM)** 
implementation("com.google.firebase:firebase-messaging")
**// TODO: Add the dependencies for Firebase products you want to use** // See https://firebase.google.com/docs/android/setup#available-libraries 
//For example, add the dependencies for Firebase Authentication and Cloud Firestore 
implementation("com.google.firebase:firebase-auth") implementation("com.google.firebase:firebase-firestore") 
}

STEP 3 : Integrate Firebase Messaging (FCM) in your app's code.

1.  Edit your app manifest :

  1. Add the following to your app's manifest:
  • A service that extends FirebaseMessagingService. This is required if you want to do any message handling beyond receiving notifications on apps in the background. To receive notifications in foregrounded apps, to receive data payload, to send upstream messages, and so on, you must extend this service.
<service 
 android:name=".fcm.MyFirebaseMessagingService" 
 android:exported="false"> 
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" /> 
</intent-filter>
</service>
  1. Optionally you can add the below lines as well in your app's manifest:
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages. -->  
<meta-data  android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification"  />  
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming  
    notification message. -->  
<meta-data  android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent"  />

<!-- From Android 8.0 (API level 26) and higher, [notification channels](https://developer.android.com/guide/topics/ui/notifiers/notifications.html#ManageChannels) are supported and recommended.
FCM provides a default notification channel with basic settings.
If you prefer to [create](https://developer.android.com/guide/topics/ui/notifiers/notifications.html#CreateChannel) and use your own default channel, set `default_notification_channel_id` to the ID of your notification channel object as shown. -->
<meta-data  android:name="com.google.firebase.messaging.default_notification_channel_id"  
android:value="@string/default_notification_channel_id"  />

2.  Request runtime notification permission on Android 13+

Android 13 introduces a new runtime permission for showing notifications. This affects all apps running on Android 13 or higher that use FCM notifications.

By default, the FCM SDK (version 23.0.6 or higher) includes the POST_NOTIFICATIONS permission defined in the manifest. However, your app will also need to request the runtime version of this permission via the constant,  android.permission.POST_NOTIFICATIONS Your app will not be allowed to show notifications until the user has granted this permission.

To request the new runtime permission:

// Declare the launcher at the top of your Activity/Fragment: 
private val requestPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission(),)
{ isGranted: Boolean -> if (isGranted) 
{ 
// FCM SDK (and your app) can post notifications. 
} 
else 
{ // TODO: Inform user that that your app will not show notifications. 
} 
} 

private fun askNotificationPermission() {
 // This is only necessary for API level >= 33 (TIRAMISU) 
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) 
 { 
 if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED ) 
 { 
 // FCM SDK (and your app) can post notifications. 
 } 
 else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) 
 { // TODO: display an educational UI explaining to the user the features that will be enabled 
 //   by them granting the POST_NOTIFICATION permission. This UI should provide the user 
 //   "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission. 
 //   If the user selects "No thanks," allow the user to continue without notifications. 
 } else 
 { 
 // Directly ask for the permission requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) 
 } 
 } 
}

3. Retrieve the current registration token

When you need to retrieve the current token, call FirebaseMessaging.getInstance().getToken() in your Activity/Fragment

Firebase.messaging.token.addOnCompleteListener(  
   OnCompleteListener { task ->  
 if (!task.isSuccessful) {  
           Log.w(TAG, "Fetching FCM registration token failed", task.exception)  
           return@OnCompleteListener  
 }  
 
 // Get new FCM registration token  
 val token = task.result  
 
 // Log and toast  
 val msg = getString(R.string.msg_token_fmt, token)  
       Log.d(TAG, msg)  
 
  //Implement this method to send token to your app server.  
 Log.d("MainActivity" ,"sendRegistrationTokenToServer($token)")  
})

4. Monitor token generation

The onNewToken callback fires whenever a new token is generated.

/**  
* Called if the FCM registration token is updated. This may occur if the security of * the previous token had been compromised. Note that this is called when the * FCM registration token is initially generated so this is where you would retrieve the token. */
override fun onNewToken(token: String) {  
Log.d(TAG, "Refreshed token: $token")  
 
// If you want to send messages to this application instance or  
// manage this apps subscriptions on the server side, send the // FCM registration token to your app server.
sendRegistrationToServer(token)  
}

That's it! Your application is ready to recieve FCM Messages.

Read the full article on Gitlab: https://gitlab.com/aampe/android-push-notifications/-/blob/Phase1/README.md?ref_type=heads