How to access payload of HMS push notifications?
In order to access the payload, you need to implement HmsMessageService class and override the method onMessageReceived. You can access your payload from the RemoteMessage Object.
To access the token, override the onNewToken method
Java code
import android.util.Log;
import com.huawei.hms.push.HmsMessageService;
import com.huawei.hms.push.RemoteMessage;
public class HService extends HmsMessageService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage != null) {
if (!remoteMessage.getData().isEmpty()) {
Log.d("HMS", "Payload" + remoteMessage.getData());
}
if (remoteMessage.getNotification() != null) {
Log.d("HMS", "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
}
}
Kotlin Code
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
super.onMessageReceived(remoteMessage)
if (remoteMessage!!.data.isNotEmpty()) {
Log.i(TAG, "Message data payload: " + remoteMessage.data)
}
if (remoteMessage.notification != null) {
Log.i(TAG, "Message Notification Body: " + remoteMessage.notification.body)
}
}
Please ensure to register your service in the manifest.
<service
android:name=".service.HService"
android:enabled="true"
android:exported="true"
android:permission="${applicationId}.permission.PROCESS_PUSH_MSG"
android:process=":HmsMessageService">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
Thanks to the nice help provided by Huawei developers (after sending them an adb shell setprop log.tag.hwpush VERBOSE
log) everything is resolved now -
In AndroidManifest.xml I have added a custom scheme app
(could be any string) as explained in the Google doc Create Deep Links to App Content:
<activity android:name="de.slova.MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="app" android:host="slova.de" />
</intent-filter>
</activity>
In MainActivity.java I have added a code for parsing intents:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// getIntent() should always return the most recent intent
handleIntent(intent);
}
private boolean handleIntent(Intent intent) {
try {
String gidStr = intent.hasExtra("gid") ?
intent.getStringExtra("gid") : // FCM notification
intent.getData().getQueryParameter("gid"); // HMS notification
Log.d(TAG, "handleIntent gidStr=" + gidStr);
int gid = Integer.parseInt(gidStr);
// show the game when user has tapped a push notification
showGame(gid);
return true;
} catch (Exception ex) {
Log.w(TAG, "handleIntent", ex);
}
return false;
}
By the way I clear push notifications when the app is started:
@Override
public void onResume() {
super.onResume();
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancelAll();
}
Finally in my game backend I first acquire token by POSTing to https://login.cloud.huawei.com/oauth2/v2/token
grant_type=client_credentials&
client_secret=MY_APP_SECRET&
client_id=MY_APP_ID
And then POST the notification https://push-api.cloud.huawei.com/v1/MY_APP_ID/messages:send using the headers Authorization: Bearer MY_TOKEN
and Content-Type: application/json; charset=UTF-8
. The JSON format is described at HMS PushKit doc.
{
"message": {
"android": {
"notification": {
"image": "https://slova.de/ws/board3?gid=108250",
"title": "Game 108250",
"body": "Alexander: Test chat msg",
"click_action": {
"type": 1,
"intent": "app://slova.de/?gid=108250"
}
}
},
"token": [
"1234567890123456789000000000DE01"
]
}
}
The HMS SDKs I currently use in my build.gradle currently are:
implementation "com.huawei.hms:base:3.0.0.301"
implementation "com.huawei.hms:hwid:3.0.0.301"
implementation "com.huawei.hms:push:3.0.0.301"
implementation "com.huawei.hms:iap:3.0.0.301"
This works well for my word game: a push notification arrives, with the title, body and small image. Then the game #108250 is opened by my app, when the user taps it: