I wrote about how to use Firebase Cloud Messaging to introduce push notifications to your Android app. In this entry, I write the code necessary to actually receive the notification and summarize the process until receiving the notification.
There are two types of FCM messages: For more information, please see here.
Message type | Overview |
---|---|
Notification message | Messages processed by FCM on behalf of the app. Since it is sent using a predefined key, it is not possible to send information other than the specified information. |
Data message | Messages that the app processes directly. The sender can freely decide the format of the message, such as the key of the message. |
There are two main differences between the two.
The behavior of the app when receiving a message is as follows. In the case where "onMessageReceived" is written, [onMessageReceived method of service inheriting FirebaseMessagingService class](https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/FirebaseMessagingService.html #onMessageReceived (com.google.firebase.messaging.RemoteMessage)) is called.
Message type | App is foreground | App is in the background |
---|---|---|
Notification message | Enter the task tray | onMessageReceived |
Data message | onMessageReceived | onMessageReceived |
Notification messages can also include data. Please refer to here for the case of using both together.
Firebase has been added to your Android project. Please check Previous entry for how to add.
It is carried out using the following environment.
Create a service that inherits from FirebaseMessagingService. This service implements the following two methods (there are other methods that can be implemented, but they are omitted here).
Method | Timing to be called |
---|---|
onNewToken | The token (character string for uniquely identifying the combination of terminal + application) has been updated. |
onMessageReceived | Received a notification |
I implemented each method. Normally, when the token is updated, processing such as saving it on the server is necessary, but here we only log it.
MyFirebaseMessagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onNewToken(String token) {
//Get a token to uniquely identify the device + app
Log.i("FIREBASE", "[SERVICE] Token = " + token);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage != null) {
//Notification message
RemoteMessage.Notification notification = remoteMessage.getNotification();
if (notification != null) {
//Handle notification messages
}
//Data message
Map<String, String> data = remoteMessage.getData();
if (data != null) {
//Process data messages
}
}
}
}
MyFirebaseMessagingService.kt
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String?) {
//Get a token to uniquely identify the device + app
Log.i("FIREBASE", "[SERVICE] Token = ${token ?: "Empty"}")
}
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
remoteMessage?.let { message ->
//Notification message
message.notification?.let {
//Handle notification messages
}
//Data message
message.data?.let {
//Process data messages
}
}
}
}
Register the created service in AndroidManifest.xml.
AndroidManifest.xml
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
"Terminal registration token" (hereinafter "token") is a character string for uniquely identifying the combination of terminal + application. Use this to send a message to your app. The token may be updated ** due to user circumstances or server side circumstances **. It is recommended to always get the latest token, so I think it is appropriate to implement it so that it is confirmed when the application starts. The code to get the token is below.
Get token(Java)
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener((task) -> {
if (!task.isSuccessful()) {
Log.w("FIREBASE", "getInstanceId failed.", task.getException());
return;
}
String token = (task.getResult() == null) ? "empty" : task.getResult().getToken();
Log.i("FIREBASE", "[CALLBACK] Token = " + token);
});
Get token(Kotlin)
FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w("FIREBASE", "getInstanceId failed", task.exception)
return@addOnCompleteListener
}
Log.i("FIREBASE", "[CALLBACK] Token = ${task.result?.token}")
}
When a message is received, onMessageReceived (RemoteMessage) implemented in a subclass of FirebaseMessagingService is called. In it, you define the logic of how to parse and handle the message. The sample code in the "Service Definition" section corresponds to each notification message and data message. please confirm.
At this point, you are ready to receive the message. You can send a message with the Firebase console or an HTTP request, so give it a try.
To send a notification message, log in to the Firebase console, open the desired project, and go to "Cloud Messaging". Click Send your first message.
If it is the second time or later, the messages sent so far are listed. Click "New Notification" at the top left of the screen to send a new message. You can also duplicate an existing message.
Then use cURL to send both the notification message and the data message. I will omit how to install and use cURL.
Check the server key. Click the gear-shaped setting icon ① on the Firebase console to open the screen. On the setting screen, click the "Cloud Messaging" tab ②. "Server key" ③ will be displayed, so make a copy of it.
The following is an example of a command that sends a data message.
SERVER_KEY=(Server key)
TARGET_TOKEN=(token)
curl -X POST -H "Content-Type:application/json" \
-H "Authorization:key=$SERVER_KEY" \
-d "{\"data\":{\"name\" : \"Taro Nihon\",\"age\" : \"20\",\"address\" : \"Tokyo\"},\"to\" : \"$TARGET_TOKEN\"}" \
https://fcm.googleapis.com/fcm/send
I wrote from writing the code to receiving the message. We've created an FCM message with minimal content here, but you can include a variety of other information such as expiration dates and priorities. Please refer to the following and try various implementations.