Spring Boot FCM Push Notification Android Example

SpringBoot FCM Notification Android Example

Tutorial: “Spring Boot FCM Push Notification Android Example – 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 – Spring Boot FCM Push Notification Example

Spring Boot FCM Push Notification Architecture
Spring Boot FCM Push Notification Architecture

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:

Spring Boot Push Notification Structure
Spring Boot FCM Push Notification 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.

SpringBoot Fcm Push Notification Server Key
Spring Boot Fcm Push Notification 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

Fcm Push Notification Result Web
Spring Boot Fcm Push Notification Result Web

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

– Android App Client in background:

SpringBoot Push Notification Result Adroid
Spring Boot Fcm Push Notification Result Adroid

– Android App Client in running foreground:

SpringBoot Result Logcat
Spring Boot Fcm Push Notification Result Logcat

Read More

Source Code

SpringBootFCMPushNotif

– Github Sourcecode:

SpringBootFCMPushNotif

Leave a Reply

Your email address will not be published. Required fields are marked *