Remote Notifications with Firebase Cloud Messaging
This walkthrough provides a step-by-step explanation of how to use Firebase Cloud Messaging to implement remote notifications (also called push notifications) in a Xamarin.Android application. It illustrates how to implement the various classes that are needed for communications with Firebase Cloud Messaging (FCM), provides examples of how to configure the Android Manifest for access to FCM, and demonstrates downstream messaging using the Firebase Console.
FCM notifications overview
In this walkthrough, a basic app called FCMClient will be created to illustrate the essentials of FCM messaging. FCMClient checks for the presence of Google Play Services, receives registration tokens from FCM, displays remote notifications that you send from the Firebase Console, and subscribes to topic messages:
The following topic areas will be explored:
Background Notifications
Topic Messages
Foreground Notifications
During this walkthrough, you will incrementally add functionality to FCMClient and run it on a device or emulator to understand how it interacts with FCM. You will use logging to witness live app transactions with FCM servers, and you will observe how notifications are generated from FCM messages that you enter into the Firebase Console Notifications GUI.
Requirements
It will be helpful to familiarize yourself with the different types of messages that can be sent by Firebase Cloud Messaging. The payload of the message will determine how a client app will receive and process the message.
Before you can proceed with this walkthrough, you must acquire the necessary credentials to use Google's FCM servers; this process is explained in Firebase Cloud Messaging. In particular, you must download the google-services.json file to use with the example code presented in this walkthrough. If you have not yet created a project in the Firebase Console (or if you have not yet downloaded the google-services.json file), see Firebase Cloud Messaging.
To run the example app, you will need an Android test device or emulator that is compatibile with Firebase. Firebase Cloud Messaging supports clients running on Android 4.0 or higher, and these devices must also have the Google Play Store app installed (Google Play Services 9.2.1 or later is required). If you do not yet have the Google Play Store app installed on your device, visit the Google Play web site to download and install it. Alternately, you can use the Android SDK emulator with Google Play Services installed instead of a test device (you do not have to install the Google Play Store if you are using the Android SDK emulator).
Start an app project
To begin, create a new empty Xamarin.Android project called FCMClient. If you are not familiar with creating Xamarin.Android projects, see Hello, Android. After the new app is created, the next step is to set the package name and install several NuGet packages that will be used for communication with FCM.
Set the package name
In Firebase Cloud Messaging, you specified a package name for the FCM-enabled app. This package name also serves as the application ID that is associated with the API key. Configure the app to use this package name:
Open the properties for the FCMClient project.
In the Android Manifest page, set the package name.
In the following example, the package name is set to com.xamarin.fcmexample
:
While you are updating the Android Manifest, also check to be sure that the
Internet
permission is enabled.
Important
The client app will be unable to receive a registration token from FCM if this package name does not exactly match the package name that was entered into the Firebase Console.
Add the Xamarin Google Play Services Base package
Because Firebase Cloud Messaging depends on Google Play Services, the Xamarin Google Play Services - Base NuGet package must be added to the Xamarin.Android project. You will need version 29.0.0.2 or later.
If you get an error during installation of the NuGet, close the FCMClient project, open it again, and retry the NuGet installation.
When you install Xamarin.GooglePlayServices.Base, all of the
necessary dependencies are also installed. Edit MainActivity.cs
and add the following using
statement:
using Android.Gms.Common;
This statement makes the GoogleApiAvailability
class in
Xamarin.GooglePlayServices.Base available to FCMClient code.
GoogleApiAvailability
is used to check for the presence of Google
Play Services.
Add the Xamarin Firebase Messaging package
To receive messages from FCM, the Xamarin Firebase - Messaging NuGet package must be added to the app project. Without this package, an Android application cannot receive messages from FCM servers.
When you install Xamarin.Firebase.Messaging, all of the necessary dependencies are also installed.
Next, edit MainActivity.cs and add the following using
statements:
using Firebase.Messaging;
using Firebase.Iid;
using Android.Util;
The first two statements make types in the Xamarin.Firebase.Messaging NuGet package available to FCMClient code. Android.Util adds logging functionality that will be used to observe transactions with FMS.
Add the Google Services JSON file
The next step is to add the google-services.json file to the root directory of your project:
Copy google-services.json to the project folder.
Add google-services.json to the app project (click Show All Files in the Solution Explorer, right click google-services.json, then select Include in Project).
Select google-services.json in the Solution Explorer window.
In the Properties pane, set the Build Action to GoogleServicesJson:
Note
If the GoogleServicesJson build action is not shown, save and close the solution, then reopen it.
When google-services.json is added to the project (and the GoogleServicesJson build action is set), the build process extracts the client ID and API key and then adds these credentials to the merged/generated AndroidManifest.xml that resides at obj/Debug/android/AndroidManifest.xml. This merge process automatically adds any permissions and other FCM elements that are needed for connection to FCM servers.
Check for Google Play Services and create a notification channel
Google recommends that Android apps check for the presence of the Google Play Services APK before accessing Google Play Services features (for more information, see Check for Google Play services).
An initial layout for the app's UI will be created first. Edit Resources/layout/Main.axml and replace its contents with the following XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:text=" "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/msgText"
android:textAppearance="?android:attr/textAppearanceMedium"
android:padding="10dp" />
</LinearLayout>
This TextView
will be used to display messages that indicate whether
Google Play Services is installed. Save the changes to Main.axml.
Edit MainActivity.cs and add the following instance variables
to the MainActivity
class:
public class MainActivity : AppCompatActivity
{
static readonly string TAG = "MainActivity";
internal static readonly string CHANNEL_ID = "my_notification_channel";
internal static readonly int NOTIFICATION_ID = 100;
TextView msgText;
The variables CHANNEL_ID
and NOTIFICATION_ID
will be used in the method CreateNotificationChannel
that will be added to MainActivity
later on in this walkthrough.
In the following example, the OnCreate
method will verify that Google
Play Services is available before the app attempts to use FCM services.
Add the following method to the MainActivity
class:
public bool IsPlayServicesAvailable ()
{
int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError (resultCode))
msgText.Text = GoogleApiAvailability.Instance.GetErrorString (resultCode);
else
{
msgText.Text = "This device is not supported";
Finish ();
}
return false;
}
else
{
msgText.Text = "Google Play Services is available.";
return true;
}
}
This code checks the device to see if the Google Play Services APK is
installed. If it is not installed, a message is displayed in the
TextBox
that instructs the user to download an APK from the Google
Play Store (or to enable it in the device's system settings).
Apps that are running on Android 8.0 (API level 26) or higher must create a notification channel for publishing their notifications. Add the following method to the MainActivity
class which will create the notification channel (if necessary):
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channel = new NotificationChannel(CHANNEL_ID,
"FCM Notifications",
NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
Replace the OnCreate
method with the following code:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
msgText = FindViewById<TextView> (Resource.Id.msgText);
IsPlayServicesAvailable ();
CreateNotificationChannel();
}
IsPlayServicesAvailable
is called at the end of OnCreate
so that
the Google Play Services check runs each time the app starts. The method
CreateNotificationChannel
is called to ensure that a notification channel
exists for devices running Android 8 or higher. If your
app has an OnResume
method, it should call IsPlayServicesAvailable
from OnResume
as well. Completely rebuild and run the app. If all
is configured properly, you should see a screen that looks like the
following screenshot:
If you don't get this result, verify that the Google Play Services APK is installed on your device (for more information, see Setting Up Google Play Services). Also verify that you have added the Xamarin.Google.Play.Services.Base package to your FCMClient project as explained earlier.
Add the instance ID receiver
The next step is to add a service that extends FirebaseInstanceIdService
to handle the creation, rotation, and updating of Firebase registration tokens. The FirebaseInstanceIdService
service is required for FCM to be able to send messages to the device. When the FirebaseInstanceIdService
service is added to the client app, the app will automatically receive FCM messages and display them as notifications whenever the app is backgrounded.
Declare the receiver in the Android Manifest
Edit AndroidManifest.xml and insert the following <receiver>
elements into the <application>
section:
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
This XML does the following:
Declares a
FirebaseInstanceIdReceiver
implementation that provides a unique identifier for each app instance. This receiver also authenticates and authorizes actions.Declares an internal
FirebaseInstanceIdInternalReceiver
implementation that is used to start services securely.The app ID is stored in the google-services.json file that was added to the project. The Xamarin.Android Firebase bindings will replace the token
${applicationId}
with the app ID; no additional code is required by the client app to provide the app ID.
The FirebaseInstanceIdReceiver
is a WakefulBroadcastReceiver
that
receives FirebaseInstanceId
and FirebaseMessaging
events and delivers
them to the class that you derive from FirebaseInstanceIdService
.
Implement the Firebase Instance ID Service
The work of registering the application with FCM is handled by the custom
FirebaseInstanceIdService
service that you provide.
FirebaseInstanceIdService
performs the following steps:
Uses the Instance ID API to generate security tokens that authorize the client app to access FCM and the app server. In return, the app gets back a registration token from FCM.
Forwards the registration token to the app server if the app server requires it.
Add a new file called MyFirebaseIIDService.cs and replace its template code with the following:
using System;
using Android.App;
using Firebase.Iid;
using Android.Util;
namespace FCMClient
{
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{
const string TAG = "MyFirebaseIIDService";
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
}
void SendRegistrationToServer(string token)
{
// Add custom implementation, as needed.
}
}
}
This service implements an OnTokenRefresh
method that is invoked when
the registration token is initially created or changed. When
OnTokenRefresh
runs, it retrieves the latest token from the
FirebaseInstanceId.Instance.Token
property (which is updated
asynchronously by FCM). In this example, the refreshed token is logged
so that it can be viewed in the output window:
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
OnTokenRefresh
is invoked infrequently: it is used to update the token
under the following circumstances:
When the app is installed or uninstalled.
When the user deletes app data.
When the app erases the Instance ID.
When the security of the token has been compromised.
According to Google's Instance ID documentation, the FCM Instance ID service will request that the app refresh its token periodically (typically, every 6 months).
OnTokenRefresh
also calls SendRegistrationToAppServer
to associate
the user's registration token with the server-side account (if any)
that is maintained by the application:
void SendRegistrationToAppServer (string token)
{
// Add custom implementation here as needed.
}
Because this implementation depends on the design of the app server, an
empty method body is provided in this example. If your app server
requires FCM registration information, modify
SendRegistrationToAppServer
to associate the user's FCM instance ID
token with any server-side account maintained by your app. (Note that
the token is opaque to the client app.)
When a token is sent to the app server, SendRegistrationToAppServer
should maintain a boolean to indicate whether the token has been sent
to the server. If this boolean is false, SendRegistrationToAppServer
sends the token to the app server – otherwise, the token was
already sent to the app server in a previous call. In some cases (such
as this FCMClient
example), the app server does not need the token;
therefore, this method is not required for this example.
Implement client app code
Now that the receiver services are in place, client app code can be
written to take advantage of these services. In the following sections,
a button is added to the UI to log the registration token (also called
the Instance ID token), and more code is added to MainActivity
to
view Intent
information when the app is launched from a notification:
Log tokens
The code added in this step is intended only for demonstration purposes
– a production client app would have no need to log registration
tokens. Edit Resources/layout/Main.axml and add the following
Button
declaration immediately after the TextView
element:
<Button
android:id="@+id/logTokenButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Log Token" />
Add the following code to the end of the MainActivity.OnCreate
method:
var logTokenButton = FindViewById<Button>(Resource.Id.logTokenButton);
logTokenButton.Click += delegate {
Log.Debug(TAG, "InstanceID token: " + FirebaseInstanceId.Instance.Token);
};
This code logs the current token to the output window when the Log Token button is tapped.
Handle notification intents
When the user taps a notification issued from FCMClient, any data
accompanying that notification message is made available in Intent
extras. Edit MainActivity.cs and add the following code to the top
of the OnCreate
method (before the call to
IsPlayServicesAvailable
):
if (Intent.Extras != null)
{
foreach (var key in Intent.Extras.KeySet())
{
var value = Intent.Extras.GetString(key);
Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
}
}
The app's launcher Intent
is fired when the user taps its
notification message, so this code will log any accompanying data in
the Intent
to the output window. If a different Intent
must be
fired, the click_action
field of the notification message must be set
to that Intent
(the launcher Intent
is used when no click_action
is specified).
Background notifications
Build and run the FCMClient app. The Log Token button is displayed:
Tap the Log Token button. A message like the following should be displayed in the IDE output window:
The long string labeled with token is the instance ID token that
you will paste into the Firebase Console – select and copy this
string to the clipboard. If you do not see an instance ID token, add
the following line to the top of the OnCreate
method to verify that
google-services.json was parsed correctly:
Log.Debug(TAG, "google app id: " + GetString(Resource.String.google_app_id));
The google_app_id
value logged to the output window should match the
mobilesdk_app_id
value recorded in google-services.json. The Resource.String.google_app_id
is generated by msbuild when processing google-services.json.
Send a message
Sign into the Firebase Console, select your project, click Notifications, and click SEND YOUR FIRST MESSAGE:
On the Compose message page, enter the message text and select Single device. Copy the instance ID token from the IDE output window and paste it into the FCM registration token field of the Firebase Console:
On the Android device (or emulator), background the app by tapping the Android Overview button and touching the home screen. When the device is ready, click SEND MESSAGE in the Firebase Console:
When the Review message dialog is displayed, click SEND. The notification icon should appear in the notification area of the device (or emulator):
Open the notification icon to view the message. The notification message should be exactly what was typed into the Message text field of the Firebase Console:
Tap the notification icon to launch the FCMClient app. The
Intent
extras sent to FCMClient are listed in the IDE output
window:
In this example, the from key is set to the Firebase project number
of the app (in this example, 41590732
), and the collapse_key is
set to its package name (com.xamarin.fcmexample).
If you do not receive a message, try deleting the FCMClient app on
the device (or emulator) and repeat the above steps.
Note
If you force-close the app, FCM will stop delivering notifications. Android prevents background service broadcasts from inadvertently or unnecessarily launching components of stopped applications. (For more information about this behavior, see Launch controls on stopped applications.) For this reason, it is necessary to manually uninstall the app each time you run it and stop it from a debug session – this forces FCM to generate a new token so that messages will continue to be received.
Add a custom default notification icon
In the previous example, the notification icon is set to the application icon. The following XML configures a custom default icon for notifications. Android displays this custom default icon for all notification messages where the notification icon is not explicitly set.
To add a custom default notification icon, add your icon to the
Resources/drawable directory, edit AndroidManifest.xml, and
insert the following <meta-data>
element into the <application>
section:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
In this example, the notification icon that resides at Resources/drawable/ic_stat_ic_notification.png will be used as the custom default notification icon. If a custom default icon is not configured in AndroidManifest.xml and no icon is set in the notification payload, Android uses the application icon as the notification icon (as seen in the notification icon screenshot above).
Handle topic messages
The code written thus far handles registration tokens and adds remote notification functionality to the app. The next example adds code that listens for topic messages and forwards them to the user as remote notifications. Topic messages are FCM messages that are sent to one or more devices that subscribe to a particular topic. For more information about topic messages, see Topic Messaging.
Subscribe to a topic
Edit Resources/layout/Main.axml and add the following Button
declaration immediately after the previous Button
element:
<Button
android:id="@+id/subscribeButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:text="Subscribe to Notifications" />
This XML adds a Subscribe to Notification button to the layout.
Edit MainActivity.cs and add the following code to the end of the
OnCreate
method:
var subscribeButton = FindViewById<Button>(Resource.Id.subscribeButton);
subscribeButton.Click += delegate {
FirebaseMessaging.Instance.SubscribeToTopic("news");
Log.Debug(TAG, "Subscribed to remote notifications");
};
This code locates the Subscribe to Notification button in the
layout and assigns its click handler to code that calls
FirebaseMessaging.Instance.SubscribeToTopic
, passing in the
subscribed topic, news. When the user taps the Subscribe
button, the app subscribes to the news topic. In the following
section, a news topic message will be sent from the Firebase
Console Notifications GUI.
Send a topic message
Uninstall the app, rebuild it, and run it again. Click the Subscribe to Notifications button:
If the app has subscribed successfully, you should see topic sync succeeded in the IDE output window:
Use the following steps to send a topic message:
In the Firebase Console, click NEW MESSAGE.
On the Compose message page, enter the message text and select Topic.
In the Topic pull-down menu, select the built-in topic, news:
On the Android device (or emulator), background the app by tapping the Android Overview button and touching the home screen.
When the device is ready, click SEND MESSAGE in the Firebase Console.
Check the IDE output window to see /topics/news in the log output:
When this message is seen in the output window, the notification icon should also appear in the notification area on the Android device. Open the notification icon to view the topic message:
If you do not receive a message, try deleting the FCMClient app on the device (or emulator) and repeat the above steps.
Foreground notifications
To receive notifications in foregrounded apps, you must implement
FirebaseMessagingService
. This service is also required for receiving
data payloads and for sending upstream messages. The following examples
illustrate how to implement a service that extends
FirebaseMessagingService
– the resulting app will be able to
handle remote notifications while it is running in the foreground.
Implement FirebaseMessagingService
The FirebaseMessagingService
service is responsible for receiving and processing the messages from Firebase. Each app must subclass this type and override the OnMessageReceived
to process an incoming message. When an app is in the foreground, the OnMessageReceived
callback will always handle the message.
Note
Apps only have 10 seconds in which to handle an incoming Firebase Cloud Message. Any work that takes longer than this should be scheduled for background execution using a library such as the Android Job Scheduler or the Firebase Job Dispatcher.
Add a new file called MyFirebaseMessagingService.cs and replace its template code with the following:
using System;
using Android.App;
using Android.Content;
using Android.Media;
using Android.Util;
using Firebase.Messaging;
namespace FCMClient
{
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(TAG, "From: " + message.From);
Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
}
}
}
Note that the MESSAGING_EVENT
intent filter must be declared so that
new FCM messages are directed to MyFirebaseMessagingService
:
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
When the client app receives a message from FCM, OnMessageReceived
extracts the message content from the passed-in RemoteMessage
object
by calling its GetNotification
method. Next, it logs the message
content so that it can be viewed in the IDE output window:
var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);
Note
If you set breakpoints in FirebaseMessagingService
,
your debugging session may or may not hit these breakpoints because of
how FCM delivers messages.
Send another message
Uninstall the app, rebuild it, run it again, and follow these steps to send another message:
In the Firebase Console, click NEW MESSAGE.
On the Compose message page, enter the message text and select Single device.
Copy the token string from the IDE output window and paste it into the FCM registration token field of the Firebase Console as before.
Ensure that the app is running in the foreground, then click SEND MESSAGE in the Firebase Console:
When the Review message dialog is displayed, click SEND.
The incoming message is logged to the IDE output window:
Add a local notification sender
In this remaining example, the incoming FCM message will be converted
into a local notification that is launched while the app is running in
the foreground. Edit MyFirebaseMessageService.cs and add the
following using
statements:
using FCMClient;
using System.Collections.Generic;
Add the following method to MyFirebaseMessagingService
:
void SendNotification(string messageBody, IDictionary<string, string> data)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
foreach (var key in data.Keys)
{
intent.PutExtra(key, data[key]);
}
var pendingIntent = PendingIntent.GetActivity(this,
MainActivity.NOTIFICATION_ID,
intent,
PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
.SetContentTitle("FCM Message")
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}
To distinguish this notification from background notifications, this code marks notifications with an icon that differs from the application icon. Add the file ic_stat_ic_notification.png to Resources/drawable and include it in the FCMClient project.
The SendNotification
method uses NotificationCompat.Builder
to create the
notification, and NotificationManagerCompat
is used to launch the
notification. The notification holds a PendingIntent
that will allow
the user to open the app and view the contents of the string passed
into messageBody
. For more information about
NotificationCompat.Builder
, see
Local Notifications.
Call the SendNotification
method at end of the OnMessageReceived
method:
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(TAG, "From: " + message.From);
var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);
SendNotification(body, message.Data);
}
As a result of these changes, SendNotification
will run whenever a
notification is received while the app is in the foreground, and the
notification will appear in the notification area.
When an app is in the background, the payload of the message will determine how the message is handled:
- Notification – messages will be sent to the system tray. A local notification will appear there. When the user taps on the notification the app will launch.
- Data – messages will be handled by
OnMessageReceived
. - Both – messages that have both a notification and data payload will be delivered to the system tray. When the app launches, the data payload will appear in the
Extras
of theIntent
that was used to start the app.
In this example, if the app is backgrounded, SendNotification
will run if the message has a data payload. Otherwise, a background notification (illustrated earlier in this walkthrough) will be launched.
Send the last message
Uninstall the app, rebuild it, run it again, then use the following steps to send the last message:
In the Firebase Console, click NEW MESSAGE.
On the Compose message page, enter the message text and select Single device.
Copy the token string from the IDE output window and paste it into the FCM registration token field of the Firebase Console as before.
Ensure that the app is running in the foreground, then click SEND MESSAGE in the Firebase Console:
This time, the message that was logged in the output window is also packaged in a new notification – the notification icon appears in the notification tray while the app is running in the foreground:
When you open the notification, you should see the last message that was sent from the Firebase Console Notifications GUI:
Disconnecting from FCM
To unsubscribe from a topic, call the UnsubscribeFromTopic method on the FirebaseMessaging class. For example, to unsubscribe from the news topic subscribed to earlier, an Unsubscribe button could be added to the layout with the following handler code:
var unSubscribeButton = FindViewById<Button>(Resource.Id.unsubscribeButton);
unSubscribeButton.Click += delegate {
FirebaseMessaging.Instance.UnsubscribeFromTopic("news");
Log.Debug(TAG, "Unsubscribed from remote notifications");
};
To unregister the device from FCM altogether, delete the instance ID by calling the DeleteInstanceId method on the FirebaseInstanceId class. For example:
FirebaseInstanceId.Instance.DeleteInstanceId();
This method call deletes the instance ID and the data associated with it. As a result, the periodic sending of FCM data to the device is halted.
Troubleshooting
The following describe issues and workarounds that may arise when using Firebase Cloud Messaging with Xamarin.Android.
FirebaseApp is not Initialized
In some cases, you may see this error message:
Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.
This is a known problem that you can work around by cleaning the solution and rebuilding the project (Build > Clean Solution, Build > Rebuild Solution).
Summary
This walkthrough detailed the steps for implementing Firebase Cloud Messaging remote notifications in a Xamarin.Android application. It described how to install the required packages needed for FCM communications, and it explained how to configure the Android Manifest for access to FCM servers. It provided example code that illustrates how to check for the presence of Google Play Services. It demonstrated how to implement an instance ID listener service that negotiates with FCM for a registration token, and it explained how this code creates background notifications while the app is backgrounded. It explained how to subscribe to topic messages, and it provided an example implementation of a message listener service that is used to receive and display remote notifications while the app is running in the foreground.