Push Notification not working after Xamarin.Forms upgrade

My app was upgraded from Xamarin.Forms 3.1 to 4.1. Before upgrade, my push notification was working perfectlty, receiving notifications when in foreground, background or closed.

After the upgrade, my app is only receiving notifications when it is in foreground or background. If my remove my app from "apps recent list" or simply do not open it after cellphone reboot, i do not receive any notification.

I am sending my notifications using firebase portal and postman. Below, is my json format:

{
   "data": {
      "title": "Título da Mensagem - data 1",
      "body": "Essa é uma mensagem longa, com muito conteúdo que precisa ser visualizado por inteiro na notificação do aplicativo !!!",
      "sound": "true"
   },
   "notification": {
      "title": "Título da Mensagem - notification 1",
      "body": "Essa é uma mensagem longa, com muito conteúdo que precisa ser visualizado por inteiro na notificação do aplicativo !!!",
      "content_available": "true"
   },
   "priority": "high",
   "to": "cezjmhzWaKM:APA91bGkEUQ......."
}

Every notification sent by postman, receives the confirmation, like the example below:

{
    "multicast_id": 2772544695401950510,
    "success": 1,
    "failure": 0,
    "canonical_ids": 0,
    "results": [
        {
            "message_id": "0:1574816910300590%6671412c6671412c"
        }
    ]
}

I do not receive any error, when my app is closed. So, I think the notification is received by my app, but it is not processed.

I am using FCM (Firebase Cloud Messaging).

Below, is my AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="215" android:versionName="2.0.9" package="com.algorix.myapp" android:installLocation="auto">
  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
  <uses-feature android:glEsVersion="0x00020000" android:required="true" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="myapp.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
  <uses-permission android:name="myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
  <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.VIBRATE" />
  <application android:label="@string/app_name" android:icon="@mipmap/icon">
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_logo_notification" />
    <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/accent_color" />
    <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>
    <uses-library android:name="org.apache.http.legacy" android:required="false" />
    <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIza......." />
  </application>
</manifest>

I have also tried add the flag "FLAG_INCLUDE_STOPPED_PACKAGES", but without any change. Below, is my class which intercepts the notifications:

    [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService
    {
    ///
        public override void OnMessageReceived(RemoteMessage message)
        {
            if (message.Data.Count > 0)
            {
                Log.Debug("Data - ", "Message data: " + message.Data.ToString());
                SendNotification(message.Data);
            }
            else
            {
                if (message.GetNotification() != null)
                {
                    Log.Debug("Notification - ", "Message notification: " + message.Data.ToString());
                    SendNotification(message.GetNotification());
                }
            }
        }

    ///
        public void SendNotification(IDictionary<string, string> data)
        {
            try
            {
                var intent = new Intent(this, typeof(MainActivity));
                intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.IncludeStoppedPackages);

                foreach (string key in data.Keys)
                {
                    intent.PutExtra(key, data[key]);
                }

                var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

                messageTitle = intent.GetStringExtra("title");
                messageBody = intent.GetStringExtra("body");
                messageSoundEnabled = intent.GetStringExtra("sound");

                SetNewAlert(messageTitle, messageBody);
                MountAlert(messageTitle, messageBody, pendingIntent);
            }
            catch (Exception ex)
            {
                _services.SendError(ex.GetType().Name, ex.Message, "Android Project", "SendNotification", _version.GetVersion());
            }
        }

    ///
        public void SendNotification(RemoteMessage.Notification notification)
        {
            try
            {
                var intent = new Intent(this, typeof(MainActivity));
                intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.IncludeStoppedPackages);
                var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

                messageTitle = notification.Title;
                messageBody = notification.Body;

                SetNewAlert(messageTitle, messageBody);
                MountAlert(messageTitle, messageBody, pendingIntent);
            }
            catch (Exception ex)
            {
                _services.SendError(ex.GetType().Name, ex.Message, "Android Project", "SendNotification", _version.GetVersion());
            }
        }

    ///
        private void MountAlert(string title, string message, PendingIntent intent)
        {
            try
            {
                string channelIdAndroid = Android.App.Application.Context.Resources.GetString(Resource.String.appnotificationchannel);
                string channelNameAndroid = "Android Channel";

                Notification.Builder notification = null;

                if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
                {
                    notification = new Notification.Builder(this, channelIdAndroid)
                                    .SetSmallIcon(Resource.Drawable.ic_stat_logo_notification)
                                    .SetContentTitle(title)
                                    .SetContentText(message)
                                    .SetAutoCancel(true)
                                    .SetStyle(new Notification.BigTextStyle().BigText(message))
                                    .SetContentIntent(intent);

                    notificationManager = NotificationManager.FromContext(this);
                }
                else
                {
                    if ((Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop) &&
                        (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O))
                    {
                        notification = new Notification.Builder(this, channelIdAndroid)
                                        .SetSmallIcon(Resource.Drawable.ic_stat_logo_notification)
                                        .SetLargeIcon(BitmapFactory.DecodeResource(Android.App.Application.Context.Resources, Resource.Mipmap.icon))
                                        .SetColor(Resource.Color.accent_color)
                                        .SetContentTitle(title)
                                        .SetContentText(message)
                                        .SetAutoCancel(true)
                                        .SetStyle(new Notification.BigTextStyle().BigText(message))
                                        .SetContentIntent(intent);

                        notificationManager = NotificationManager.FromContext(this);
                    }
                    else
                    {
                        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
                        {
                            NotificationChannel androidChannel = new NotificationChannel(channelIdAndroid, channelNameAndroid, NotificationImportance.Default);
                            androidChannel.EnableVibration(true);
                            androidChannel.SetSound(null, null);
                            androidChannel.ShouldShowLights();
                            androidChannel.EnableLights(true);
                            androidChannel.SetShowBadge(true);
                            androidChannel.LightColor = Resource.Color.accent_color;
                            androidChannel.LockscreenVisibility = NotificationVisibility.Public;

                            notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);

                            notificationManager.CreateNotificationChannel(androidChannel);

                            notification = new Notification.Builder(this, channelIdAndroid)
                                            .SetSmallIcon(Resource.Drawable.ic_stat_logo_notification)
                                            .SetLargeIcon(BitmapFactory.DecodeResource(Android.App.Application.Context.Resources, Resource.Mipmap.icon))
                                            .SetColor(Resource.Color.accent_color)
                                            .SetContentTitle(title)
                                            .SetContentText(message)
                                            .SetAutoCancel(true)
                                            .SetStyle(new Notification.BigTextStyle().BigText(message))
                                            .SetContentIntent(intent);

                        }
                    }
                }

                if (notificationManager != null && notification != null)
                {
                    notificationManager.Notify(RandomGenerator(), notification.Build());

                    if (messageSoundEnabled != null && messageSoundEnabled.Length > 0)
                    {
                        bool soundEnabled;
                        bool.TryParse(messageSoundEnabled, out soundEnabled);

                        if (soundEnabled)
                        {
                            var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
                            player.Load("notification.mp3");
                            player.Play();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _services.SendError(ex.GetType().Name, ex.Message, "Android Project", "MountAlert", _version.GetVersion());
            }
        }

And my last try, was to upgrade Xamarin.Forms to 4.3, but also nothing happenned.

Please, any clue to solve this problem ???

Answers

  • jezhjezh Member, Xamarin Team Xamurai
  • olivertech2016olivertech2016 BRMember ✭✭

    jezh, One new thing I think could be used to verify this problem is...Nowadays, we have 37 apps, somo of them are in 32 bits version yet... Those apps, the push notification works in foreground, background and stopped.

    But we have some other apps in 64 bits version, and on those one, the push notification do no work, when the app is in stopped status.

  • Loki606Loki606 Member ✭✭

    Xamarin.Firebase.Messaging v71 implementation no longer works, no matter which guide you try to follow.

  • jezhjezh Member, Xamarin Team Xamurai

    I will try to test this question and come back ASAP.

  • I agree with @Loki606, I have not been able to find any guide, solution or sample project that accurately describes how to use the new updated Xamarin.Firebase.Messaging v71 class now that they have removed the FirebaseInstanceID class. All guides seems to still use FirebaseInstanceID class yet it is deprecated and will cause an error if attempted to be used. Microsofts own walkthrough documentation is outdated and have 9 open questions/issues.

    I can only get the following to work with the new Xamarin.Firebase.Messaging v71 @jezh
    iOS
    App active: notification recieved
    App in background: notification recieved
    App killed: notification recieved

    Android
    App active: notification recieved
    App in background: notification recieved
    App killed: notification never arrives

  • Same issue. Any clues?

  • Loki606Loki606 Member ✭✭

    @XamarinProblems can you please share a guide on how you did it? I can't even get as far as to receive notification when app is active.

  • XamarinProblemsXamarinProblems Member ✭✭

    Which platform @Loki606? the requirements are different on iOS and Android to make firebase work

  • Loki606Loki606 Member ✭✭
    edited January 13

    Android API 28.0, library FirebaseMessaging Nuget v.71. All the NuGet packages I'm using are the latest

    I should mention however that I managed to get PushNotifications working regardless of app state, but it's with theOneSignal plugin. It works amazingly, I definitely recommend it.

  • XamarinProblemsXamarinProblems Member ✭✭
    edited January 13

    Good to hear you have gotten it to work, Quick run down of what you have to do on Android to get the messages, assuming you have the sending of them under control:

    1. Add the google-service.json object to your solution and make sure the build action is GoogleServiceJson (look under properties in the visual studio explorer)
    2. Add the needed permissions and services to the Android Manifest.

    First thing:

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE">
    

    Second thing:

    <application android:label="AppName" android:icon="@drawable/icon" android:allowBackup="false">
        <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_white_icon" />
            <service android:name=".FirebaseMessagingService" android:stopWithTask="false">
                <intent-filter>
                    <action android:name="com.google.firebase.MESSAGING_EVENT" />
                </intent-filter>
            </service>
        <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>
    

    1. And then you need the FireBaseMessagingService.cs file posted further up. Having that should allow you to recieve messages if you are sending them correctly with the FireBase Api
  • Loki606Loki606 Member ✭✭

    damn... i didn't have that permission added... I also replaced ${applicationId} with my actual application ID and it works now! Thank you!!! <3

Sign In or Register to comment.