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.
- Method 1. Receive messages while running
- Method 2. Handle app entry from a notification tap
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
NotificationReceivedevent. - 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().
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
Successis returned, ifMessageisnull, 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.Datadictionary.
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. |
Related documents
The following documents are related to the content of this document.