Skip to content

Step 5. Receive remote push notifications

Handle remote push messages that arrive on Android in the app client.

This document describes how to receive messages while the app is running with the Hive Axyl FCM plugin and how to check the payload when the user launches the app by tapping a notification.


You can implement FCM push reception handling in the following ways.

The FCM plugin provides only receive events and cold start message retrieval. The app client itself handles how messages are displayed, how data is interpreted, and screen navigation.

Note
  • The FCM plugin is for Android devices only. In other environments, including the Unity Editor, the port is not registered, so guard it with OS branching or HiveCore.TryResolve<T>().
  • Messages that arrive in the background and are displayed as system notifications are handled directly by the OS, so app code is not involved.


Method 1. Receive messages while running

When a remote message arrives while the app can receive messages, the NotificationReceived event occurs. The event is delivered on the engine main thread, so you can work with the UI directly in the handler.

Depending on FCM SDK behavior, the event occurs under the following conditions.

  • Foreground: Occurs for all messages.
  • Background: Occurs only for data messages. Notification messages are displayed as system notifications, and the event does not occur.


Call example

using Hive.Axyl.Core;
using Hive.Axyl.Push.Addon.FCM;

IFCMPlugin fcm = HiveCore.Resolve<IFCMPlugin>();

fcm.NotificationReceived += message =>
{
    // Foreground reception - the app decides what to do, such as showing an in-app banner.
    // For data-only messages, message.Notification is null.
    string title = message.Notification?.Title ?? string.Empty;
    string body  = message.Notification?.Body ?? string.Empty;

    if (message.Data.TryGetValue("deepLink", out var deepLink))
    {
        // Interpret and handle the data keys that the app defined.
    }
};


Considerations when calling

  • The FCM plugin instance must be kept alive to receive the NotificationReceived event.
  • The app client decides how to display notifications in the foreground.
  • Background notification messages are displayed by the OS as system notifications. When the user launches the app by tapping a notification, use Handle app entry from a notification tap.


Method 2. Handle app entry from a notification tap

When the user launches the app or brings it back to the front by tapping a notification, get the data payload of that notification with GetColdStartMessageAsync().

Method

public Task GetColdStartMessageAsync();


The cold start message buffer is single-use. For a normal launch, or after the message has already been taken out once, Success is returned with Message set to null, and this is not a failure. Call it once at app startup to check whether the app was entered from a notification tap.

Note

When the app is launched from a notification tap while it is not running (cold launch), it works without additional settings. To also receive the payload when the app is re-entered from a notification tap while it is running (warm tap), the host Activity must forward onNewIntent to Hive Axyl.


Call parameters

Field name Type Required Description
ct CancellationToken Optional The cancellation token used to cancel the call. If omitted, the default value is used.


Call example

The return object of GetColdStartMessageAsync(), FcmServiceGetColdStartMessageResult, is divided into success and failure states. The method call does not throw exceptions (Exception), and all processing results are delivered through the return object. Therefore, instead of using a separate try/catch statement, branch on the response status with a switch statement.

using Hive.Axyl.Core;
using Hive.Axyl.Push.Addon.FCM;

FcmServiceGetColdStartMessageResult result = await fcm.GetColdStartMessageAsync();

switch (result)
{
    case FcmServiceGetColdStartMessageResult.Success success when success.Data.Message != null:
        // Entered from a notification tap - interpret the payload and handle it, such as by moving to a specific screen.
        var data = success.Data.Message.Data;
        break;

    case FcmServiceGetColdStartMessageResult.Success:
        // Normal launch or a buffer already taken out - there is no notification to handle.
        break;

    // Handle common failures - for the detailed error model, see [Error handling](PLACEHOLDER_에러처리_링크)
    case FcmServiceGetColdStartMessageResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // Safety net: unknown new results
    default:
        Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
        break;
}


Considerations when calling

  • Call it once at app startup to check whether the app was entered from a notification tap.
  • Even if Success is returned, if Message is null, it is a normal launch or a buffer that was already taken out.
  • When you navigate screens based on the payload, do so after app initialization and the login status check are complete.


Response data

On success, Data of FcmServiceGetColdStartMessageResult.Success contains the message.

Field name Type Required Description
Data.Message FcmRemoteMessage Optional The payload of the notification the user tapped. null for a normal launch or if the buffer was already taken out.


Response status

The return object FcmServiceGetColdStartMessageResult branches into the following cases. Handle it with a switch statement.

Response case Description App client handling
Success The retrieval succeeded. For entry from a notification tap, Message contains the payload; for a normal launch, it is null. Branch on whether Message is present
Failure Native integration error. Problem (HiveError) contains the details. Treat it as a normal launch or log the error


For reference. Check received message data

An FCM message can consist of two parts.

  • Notification: Content that the OS displays, such as the title and body. It is delivered as FcmRemoteMessage.Notification.
  • Data: A key-value payload that the app interprets. It is delivered as the FcmRemoteMessage.Data dictionary.

The app interprets the keys of the received Data to implement behavior such as screen navigation and state updates. Data is delivered bundled with a displayed notification, and whether a message that contains only data (silent push, data-only) can be sent follows the push sending (server) specification.


For reference: FcmRemoteMessage structure

A received message has a structure that carries over FCM's remote message (RemoteMessage) as is.

Field name Type Required Description
MessageId string Required The message identifier.
SentTime DateTimeOffset Required The sending time (UTC).
From string Required The sender.
CollapseKey string Required The message collapse key.
Priority int Required The delivery priority. 0 is unknown, 1 is high, and 2 is normal.
Ttl TimeSpan Required The message validity period.
Data IReadOnlyDictionary<string,string> Required The data payload. If there is no data, it is an empty dictionary (not null).
Notification FcmNotification Optional Notification display information. null for a data-only message.

FcmNotification

Field name Type Required Description
Title string Required The notification title. If there is no value, it is an empty string (not null; the same applies to the string fields below).
Body string Required The notification body.
ImageUrl string Required The notification image URL.
Icon string Required The notification icon.
Sound string Required The notification sound.
Tag string Required The notification tag.
ClickAction string Required The action to run when the notification is tapped.
ChannelId string Required The Android notification channel ID.
Color string Required The notification color.
Link string Required The notification link URL.
TitleLocKey string Required The title localization key.
BodyLocKey string Required The body localization key.
TitleLocArgs IReadOnlyList<string> Required The title localization arguments. An empty list if there are none.
BodyLocArgs IReadOnlyList<string> Required The body localization arguments. An empty list if there are none.


The following documents are related to the content of this document.