What is the best way to handle both Notification Messages and Data Messages in firebase using Xamarin Android, while the user is in Foreground and Background?
Also, how do i get the notification data, for example, the text of a particular notification?
PS: I have visited the following threads and none actually helped :
When device screen off then how to handle firebase notification?
Firebase Notification and Data
Display firebase notification data-message on Android tray
Well, I found the answers to my own question so I'm posting the answer for someone who is looking for firebase integration in xamarin.
Install Xamarin.Firebase.Messaging
package to your project.
Add the following code to your manifest.xml to receive firebase notifications.
<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>
Now to get the registration token from firebase add a class file and add the following code to it:
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{
public override void OnTokenRefresh()
{
const string TAG = "MyFirebaseIIDService";
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
}
void SendRegistrationToServer(string token)
{
// Add custom implementation, as needed.
}
}
Here FirebaseInstanceId.Instance.Token
gets the instance token for the current device, Also the method SendRegistrationToServer
can be used to send the token to send the token to a server.
Now add another class to handle notifications on foreground
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
// private string TAG = "MyFirebaseMsgService";
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
string messageFrom = message.From;
string getMessageBody = message.GetNotification().Body;
SendNotification(message.GetNotification().Body);
}
void SendNotification(string messageBody)
{
try
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
.SetContentTitle("Title")
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(0, notificationBuilder.Build());
}
catch (Exception ex)
{
}
}
}
Here the method SendNotification
is used to explicitly send a notification to the system tray, Since push notifications while the device is in the foreground are not automatically displayed in the system tray.
When the device is in the background or killed notification is automatically generated and by default the main launcher activity is loaded, to get the data from the background notification you need to use intent as follows(On your main launcher activity):
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);
}
}
Also if google play services are not up to date this code might crash your application so to check if google play services are available or not do this :
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;
}
}
Check the below link for information on how to add your project to the firebase console:
https://developer.xamarin.com/guides/android/data-and-cloud-services/google-messaging/remote-notifications-with-fcm/