0

I'm wondering in what class can I specify how to handle a notification that gets sent while the app is either closed or in the background. Right now I get notifications locally which then triggers my SendLocalNotification method to structure it the way that I'd like and this is what I'm wanting to happen for notifications while the app is closed or in the background too. I still receive background notifications but they don't trigger any of the code that structures what it should look like.

I did some digging and read a few things about overriding a method to handle remote notifications but couldn't quite find a good example or even the specific method to override.

Here's my OnMessageReceived override in my FirebaseService class (ignore the code that looks out of place. I've been messing around with stuff):

public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        string messageBody = string.Empty;

        if (message.GetNotification() != null)
        {
            switch (message.GetNotification().Title)
            {
                case "Load Matched":
                    break;
            }
            messageBody = message.GetNotification().Body;
        }
        else
        {
            messageBody = message.Data.Values.First();
        }
        try
        {
            MessagingCenter.Send(messageBody, "Update");
        }
        catch (Exception e)
        { 
        }
        SendLocalNotification(messageBody);
    } 

And here is my SendLocalNotification method. I'd love for remote notifications to also trigger this method so they could look the same.

void SendLocalNotification(string body)
    {
        //Unique request code to avoid PendingIntent collision.
        var requestCode = new Random().Next();

        // accept intent
        var acceptIntent = new Intent(this, typeof(MainActivity));
        acceptIntent.SetAction("ACCEPT_ACTION");
        var pendingIntentAccept = PendingIntent.GetActivity(this, requestCode, acceptIntent, PendingIntentFlags.OneShot);

        // decline intent
        var declineIntent = new Intent(this, typeof(MainActivity));
        declineIntent.SetAction("DECLINE_ACTION");
        var pendingIntentDecline = PendingIntent.GetActivity(this, requestCode, declineIntent, PendingIntentFlags.OneShot);

        var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.SingleTop);

        var notificationBuilder = new NotificationCompat.Builder(this)
            .AddAction(0, "Accept", pendingIntentAccept)
            .AddAction(0, "Decline", pendingIntentDecline)

            .SetContentTitle("Content Title")
            .SetSmallIcon(Resource.Drawable.laundry_basket_icon_15875)
            .SetContentText("content text")
            .SetContentInfo("content info")
            .SetSubText("sub text")
            .SetAutoCancel(true)
            .SetShowWhen(true)
            .SetContentIntent(pendingIntentAccept)
            .SetContentIntent(pendingIntentDecline);

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
        }

        var notificationManager = NotificationManager.FromContext(this);
        notificationManager.Notify(0, notificationBuilder.Build());
    }

EDIT: Here is the code that I'm using to send my notification. I was under the impression that having a data tag meant that a data notification was being sent which would then get picked up by OnMessageReceived.

public void SendNotificationByTag(string tag, string notificationBody = "", string notificationTitle = "")
    {
        var url = $"{_baseUrl}/messages/?api-version=2015-01";
        var client = new RestClient($"{url}");
        var request = new RestRequest(Method.POST);
        request.AddHeader("Content-Type", "application/json");
        request.AddHeader("ServiceBusNotification-Format", "gcm");            
        request.AddHeader("ServiceBusNotification-Tags", $"{tag}");
        request.AddHeader("Authorization", $"{NotificationHelper.CreateSasToken(url, "DefaultFullSharedAccessSignature", $"{_configuration["DefaultFullSharedAccessSignature"]}")}");
        request.AddParameter("application/json", $"{{\"data\":\n\t{{\n\t\t\"gcm.notification.body\":\"{notificationBody}\", \n\t\t\"gcm.notification.title\":\"{notificationTitle}\",\n\t}}\n}}", ParameterType.RequestBody);
        client.Execute(request);
    }
user1818298
  • 509
  • 2
  • 8
  • 23

2 Answers2

1

Firebase Cloud Messaging support two primary message types:

  • Notification messages, sometimes thought of as "display messages." These are handled by the FCM SDK automatically.

  • Data messages, which are handled by the client app.

It sounds like you're sending a notification message. When your app is not active, those are handled by the OS/SDK automatically and are displayed in the system tray without your code being invoked.

If you always want your OnMessageReceived to be called, you should only send data messages.

Also see: How to handle notification when app in background in Firebase

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • i thought by having a data tag it meant that it was sending the data message. ill update my post with the code that im using to send my notification. – user1818298 Apr 21 '20 at 02:44
  • @user1818298 Firebase will not call your onMessageReceived() when your app is in the background or killed, and you can't customise your notification. It will show notifications managed by Firebase it self.To make Firebase library to call your onMessageReceived() in every case.Do not put JSON key "notification" in your request to Firebase API, use "data" instead, please read [this](https://stackoverflow.com/questions/45671869/firebase-onmessagereceived-not-called) and [this](https://stackoverflow.com/questions/45875859/fcm-onmessagereceived-not-calling-android) – Cherry Bu - MSFT Apr 22 '20 at 08:40
  • @CherryBu-MSFT im using a data request. you can see in my question the code im using to send the notification contains the data key in the request payload body. – user1818298 Apr 22 '20 at 12:41
  • Thanks for adding the information to your question. The way the properties are handled is fairly basic, so my first guess is that the `notification.title` is still making it be handled as a notification message. You might want to try with property names that are less likely to confuse the SDK, for example `title`. – Frank van Puffelen Apr 22 '20 at 14:32
0

So it looks like the culprit was having gcm.notification.title and gcm.notification.body in the request. Even though it was inside a data tag it looks like it was still passing it through as a notification message. When I replaced those 2 keys with regular title and body tags then I started hitting my OnMessageReceived while the app was in the background.

user1818298
  • 509
  • 2
  • 8
  • 23