Tutorial: “How to Implement Push Notification in Spring Boot – Firebase Cloud Messaging”
In the article Firebase Cloud Messaging – How to Subscribe TOPIC & Receive Messages | Android, we have created an Android App that can subscribe/unsubscribe specific TOPIC and receive Message Data, but we used Firebase Notification Console GUI to generate Notification. Today, we’re gonna look at way to create a Spring Boot Application Server that can make message and push notification to Android Client via Firebase.
Related Post: Firebase Cloud Messaging – XMPP Server example to receive Upstream Messages | Spring Integration
Overview Architecture – How to Implement Push Notification in Spring Boot

1. Topic HTTP POST: Send to a single topic loizenjava
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=SERVER_KEY
{
"to": "/topics/loizenjava",
"notification": {
"title": "TITLE",
"body": "BODY"
},
"data": {
"Key-1": "VALUE 1",
"Key-2": "VALUE 2"
},
}
Send to devices subscribed to topics ABC or XYZ:
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=SERVER_KEY
{
"condition": "'ABC' in topics || 'XYZ' in topics",
"data": {
...
}
}
This is the response:
// Success:
{
"message_id": "123456"
}
// failure example:
{
"error": "TopicsMessageRateExceeded"
}
3. Technology:
– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.4.RELEASE
– Spring Boot: 2.0.0.M2
4. Project Structure:

– AndroidPushNotificationsService
is the service that provides send()
method (with ClientHttpRequestInterceptor
and RestTemplate
POST request) to Firebase FCM.
– WebController
is a REST Controller that creates Message Data Entity and uses Service above to push Notification.
Firebase Get Server Key – Spring Boot FCM Push Notification Android Example
Go to Settings of your Firebase Project in Firebase Console to get Server Key.

Create Spring Boot project – Spring Boot FCM Push Notification Android Example
– Using Spring Tool Suite/Eclipse to create Spring Boot project.
– Add Dependencies to pom.xml file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
SpringBoot Create Push Notification Service – Spring Boot FCM Push Notification Android Example
package com.loizenjava.fcm.pushnotif.service;
import java.io.IOException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.support.HttpRequestWrapper;
public class HeaderRequestInterceptor implements ClientHttpRequestInterceptor {
private final String headerName;
private final String headerValue;
public HeaderRequestInterceptor(String headerName, String headerValue) {
this.headerName = headerName;
this.headerValue = headerValue;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
HttpRequest wrapper = new HttpRequestWrapper(request);
wrapper.getHeaders().set(headerName, headerValue);
return execution.execute(wrapper, body);
}
}
Remember to copy your Server Key at the first step to FIREBASE_SERVER_KEY
.
package com.loizenjava.fcm.pushnotif.service;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import org.springframework.http.HttpEntity;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class AndroidPushNotificationsService {
private static final String FIREBASE_SERVER_KEY = "Your Server Key here!";
private static final String FIREBASE_API_URL = "https://fcm.googleapis.com/fcm/send";
@Async
public CompletableFuture send(HttpEntity entity) {
RestTemplate restTemplate = new RestTemplate();
/**
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=FIREBASE_SERVER_KEY*/
ArrayList interceptors = new ArrayList<>();
interceptors.add(new HeaderRequestInterceptor("Authorization", "key=" + FIREBASE_SERVER_KEY));
interceptors.add(new HeaderRequestInterceptor("Content-Type", "application/json"));
restTemplate.setInterceptors(interceptors);
String firebaseResponse = restTemplate.postForObject(FIREBASE_API_URL, entity, String.class);
return CompletableFuture.completedFuture(firebaseResponse);
}
}
SpringBoot Create RestAPI Controller
package com.loizenjava.fcm.pushnotif.controller;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.loizenjava.fcm.pushnotif.service.AndroidPushNotificationsService;
@RestController
public class WebController {
private final String TOPIC = "loizenjava";
@Autowired
AndroidPushNotificationsService androidPushNotificationsService;
@RequestMapping(value = "/send", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> send() throws JSONException {
JSONObject body = new JSONObject();
body.put("to", "/topics/" + TOPIC);
body.put("priority", "high");
JSONObject notification = new JSONObject();
notification.put("title", "JSA Notification");
notification.put("body", "Happy Message!");
JSONObject data = new JSONObject();
data.put("Key-1", "JSA Data 1");
data.put("Key-2", "JSA Data 2");
body.put("notification", notification);
body.put("data", data);
/**
{
"notification": {
"title": "JSA Notification",
"body": "Happy Message!"
},
"data": {
"Key-1": "JSA Data 1",
"Key-2": "JSA Data 2"
},
"to": "/topics/loizenjava",
"priority": "high"
}
*/
HttpEntity<String> request = new HttpEntity<>(body.toString());
CompletableFuture<String> pushNotification = androidPushNotificationsService.send(request);
CompletableFuture.allOf(pushNotification).join();
try {
String firebaseResponse = pushNotification.get();
return new ResponseEntity<>(firebaseResponse, HttpStatus.OK);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return new ResponseEntity<>("Push Notification ERROR!", HttpStatus.BAD_REQUEST);
}
}
Run & Check Result
– Config maven build:
clean install
– Run project with mode Spring Boot App.
– Open Browser, enter URL:
http://localhost:8080/send

Look back to the Android App Client that can subscribe/unsubscribe TOPIC and receive Message:
– Android App Client in background:

– Android App Client in running foreground:

Read More
Source Code
– Github Sourcecode: