Search code examples
androidfirebasepush-notificationxamarin.androidfirebase-cloud-messaging

OnMessageRecieved not getting fired in background app


I'm trying to get redirect to a diffrent paged on clicking diffrent notifications. The OnMessagedRecieved isn't getting triggered when the app is running in the background only when its on the foreground.

According to the documentation notification foreground, background its the System tray that gets triggered.

So i looked up how to get it working on the background, I found this tutorial.

Accordign to this tutorial:

As explained below, by using FCM console you can only send notification messages. notification messages can be handled by the onMessageReceived method in foregrounded application and deliver to the device’s system tray in backgrounded application. User taps on notification and default application launcher will be opened. if you want to handle notification in every state of application you must use data message and onMessageReceived method.

So i looked up what exactly a data message is and what a notification message is. Documentation

I folowed the tutorial but its not working for me. This is my code :

public async Task<bool> WakeUp(string[] tokens)
    {
        var message = new Message()
        {
            RegistrationID= tokens,
            Notification = new Notification()
            {
                Title = "testing",
                Body = "test"
            },
            Android = new AndroidConfig()
            {
                Notification = new AndroidNotification()
                {
                    Color = "#FF0000",
                    ClickAction = "MyActivity"
                }
            },
            Data = new Dictionary<string, string>()
            {
                {
                    "notificationType", NotificationType.WakeUp.ToString()
                }
            }
        };

        return await SendAsyncMessage(message).ConfigureAwait(false);
    }


public async Task<bool> SendAsyncMessage(Message message)
    {
        var jsonMessage = JsonConvert.SerializeObject(message);
        var request = new HttpRequestMessage(HttpMethod, FIREBASE_PUSH_NOTIFICATION_URL)
        {
            Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json")
        };
        request.Headers.TryAddWithoutValidation("Authorization", $"key={ConfigurationManager.AppSettings["FirebaseNotificationServerKey"]}");
        request.Headers.TryAddWithoutValidation("Sender", $"id={ConfigurationManager.AppSettings["FirebaseNotificationSenderID"]}");
        HttpResponseMessage result;
        using (var client = new HttpClient())
        {
            result = await client.SendAsync(request).ConfigureAwait(false);
        }

        return result.IsSuccessStatusCode;
    }

This is how i recieve my code in my app

public override void OnMessageReceived(RemoteMessage message)
    {
       Console.WriteLine("message recieved");
    }

Raw Json

{
"registration_ids":["myToken"],
"condition":null,
"data":
{
    "notificationType":"WakeUp"
},
"notification":
{
    "title":"testing",
    "body":"test",
    "image":null
},
"android":
{
    "collapse_key":null,
    "restricted_package_name":null,
    "data":null,
    "notification":
    {
        "title":null,
        "body":null,
        "icon":null,
        "color":"#FF0000",
        "sound":null,
        "tag":null,
        "image":null,
        "click_action":"mActivity",
        "title_loc_key":null,
        "title_loc_args":null,
        "body_loc_key":null,
        "body_loc_args":null,
        "channel_id":null
    },
    "fcm_options":null,
    "priority":"high",
    "ttl":null
},
"webpush":null,
"apns":null,
"fcm_options":null,
"topic":null

}

The notification is recieved but the OnMessageRecieved isn't triggered. I think the notification center is the one responsible for the notification being shown.

What could be the problem?


Solution

  • 1. Why is this happening?

    There are two types of messages in FCM (Firebase Cloud Messaging):

    1. Display Messages: These messages trigger the onMessageReceived() callback only when your app is in foreground
    2. Data Messages: Theses messages trigger the onMessageReceived() callback even if your app is in foreground/background/killed

    NOTE: Firebase team have not developed a UI to send data-messages to your devices, yet. You should use your server for sending this type!



    2. How to?

    To achieve this, you have to perform a POST request to the following URL:

    POST https://fcm.googleapis.com/fcm/send

    Headers

    • Key: Content-Type, Value: application/json
    • Key: Authorization, Value: key=<your-server-key>

    Body using topics

    {
        "to": "/topics/my_topic",
        "data": {
            "my_custom_key": "my_custom_value",
            "my_custom_key2": true
         }
    }
    

    Or if you want to send it to specific devices

    {
        "data": {
            "my_custom_key": "my_custom_value",
            "my_custom_key2": true
         },
        "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
    }
    


    NOTE: Be sure you're not adding JSON key notification
    NOTE: To get your server key, you can find it in the firebase console: Your project -> settings -> Project settings -> Cloud messaging -> Server Key

    3. How to handle the push notification message?

    This is how you handle the received message:

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) { 
         Map<String, String> data = remoteMessage.getData();
         String myCustomKey = data.get("my_custom_key");
    
         // Manage data
    }
    

    this is refer to here