Spring Boot Android FCM Example

Mobile apps are more engaging with notifications. For relatively large mobile app often needs a backend. Mobile Back End as a Service or MBAAS is a very good choice nowadays. But most of the time we could not cover all the requirements from it. So we end up having at least a very narrow scoped backend service which is unique for the app business domain. Spring Boot defacto framework for Java house, so here I am going to share how we can use Firebase (popular MBAAS from google) cloud messaging in a spring boot application. So let’s get started with SpringBoot Android FCM example.

Using Firebase SDK for Spring Boot Firebase Cloud Messaging

There are several ways of using FCM and here we are going to use Java SDK. It uses FCM HTTP v1 underneath. You can also consume raw API without using the admin SDK. Also, you can use the XMPP protocol for specific scenarios.

Setting up Spring Boot App For Spring Boot Android FCM Example

First, you should have a firebase project. If you don’t please read my previous article. Then you should have the config file downloaded. you can do it on the following screen. Unfortunately, we cannot use the spring cloud GCP project for this because it’s still not supported for FCM. But the process is fairly straight forward. Let’s use spring initializer, I am using Java and maven. Next let’s grab the additional dependencies we need.

<dependency>
  <groupId>com.google.firebase</groupId>
  <artifactId>firebase-admin</artifactId>
  <version>7.1.0</version>
</dependency>

Placing Service Account Key file

you can include the key file in src/main/resources. But make sure not to commit it. So it would be safe if you add it to the .gitignore file first. But you have to ship this file with the application so make sure your deployable is stored in a secure location and your runtime is secured from outside access.

Spring Boot Firebase Bean

First, we need to create a FirebaseApp bean so we can use Spring DI to inject it whenever we want.

@Bean
public FirebaseApp initFirebaseApp() throws IOException {
    InputStream serviceAccount = SpringBootFcmExampleApplication.class.getResourceAsStream("/xxxx.json");

    FirebaseOptions options = FirebaseOptions.builder()
            .setCredentials(GoogleCredentials.fromStream(serviceAccount))
            .build();

    FirebaseApp.initializeApp(options);

    return FirebaseApp.getInstance();
}

Spring Boot FCM Service

Let’s create a Service that exposes methods to send FCM message to a device using its registration token.

package com.aptkode.springbootfcmexample;

import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.FirebaseMessagingException;
import com.google.firebase.messaging.Message;
import com.google.firebase.messaging.Notification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class FCMService {

    private static final Logger logger = LoggerFactory.getLogger(FCMService.class);

    private final FirebaseApp firebaseApp;

    @Autowired
    public FCMService(FirebaseApp firebaseApp) {
        this.firebaseApp = firebaseApp;
    }

    public Optional<String> sendNotification(String token, String title, String body) {
        Message message = Message.builder()
                .setNotification(Notification.builder().setTitle(title).setBody(body).build())
                .setToken(token)
                .build();
        try {
            String response = FirebaseMessaging.getInstance(firebaseApp).send(message);
            logger.info("fcm message sent. response: {}", response);
            return Optional.of(response);
        } catch (FirebaseMessagingException e) {
            logger.error("failed to send fcm message error code: {} message: {}", e.getErrorCode(), e.getMessage());
        }
        return Optional.empty();
    }
}

Let’s write a code to test this. To send a message we need a device registration token, so we can send a notification to that device. How can we get a registration token? In your mobile app, there should be a mechanism to send its device registration token to the backend. I am not going to explain how to send the message rather android app registration with FCM. So you can use that token to test out the FCM Service we just wrote. You can decide how you are going to handle device token sync with the backend.

Setting up the android app for Spring Boot Android FCM Example

Time needed: 20 minutes.

First thing, you need to download google-services.json from the firebase project. Then following steps need to be carried out to set up your fresh android app to configure firebase integration.

  1. Create app in Firebase

    Add new app with required data, then download the google-services.json file and put it in the root of the app module. Package name would be your app’s package which is in the manifest. To generate SHA certificates fingerprints, you can use following Gradle task. Task will list down all SHA fingerprints for available flavors.

  2. Add google() to repositories to top-level build Gradle

  3. Add classpath dependency for google play services plugin

  4. Place plugin in app’s build.gradle

  5. Add firebase BOM

  6. List required FCM dependencies in dependencies section
    note that BOM is little bit different.

  7. Add service which extends FirebaseMessagingService and add it to manifest

  8. Override onNewToken method

now you are ready to install the app and get the registration token. But I haven’t implemented the app code to show the notification. I hope you could implement that easily. But default notification will be popped up when your app is in background. Following test produces the notification in mobile app.

package com.aptkode.springbootfcmexample;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertTrue;

@SpringBootTest
class FCMTest {

    @Autowired
    private FCMService fcmService;

    @Test
    void sendNotificationTest() {
        final Optional<String> response = fcmService.sendNotification("xxxxxxxxxxxxxxxxxxxxxx",
                "test-notification",
                "test-body");
        assertTrue(response.isPresent());
    }
}
notification for spring boot test

I hope you’ve learned how to use Firebase cloud messaging in a SpringBoot Android system. You can easily apply this for iPhone app as well. Here are Spring Boot App and Android App source code if you want to play around. Thanks for reading.

Leave a Comment

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