Send push notifications from Spring Boot server-side application using FCM

As you probably noticed, I familiarize myself with the subject of Firebase Cloud Messaging push notifications recently.

This time I would like to share with you my push notifications server-side application. The app is made with the Spring Boot framework.

The provided example covers most common notifications sending use cases such as: sending push notification to a topic, directly to the users’ device, or sending messages with additional data payload.

This post is not a step-by-step tutorial. I’ll focus on the most important parts. A fully working example is available on GitHub.

If you don’t have a client-side application to receive push notifications yet, you should consider the use of the Ionic app I described earlier. Have fun!

Let’s go

Let’s start with the Firebase integration.

First of all, you have to generate your own Firebase SDK admin key. Basically, it’s a JSON file with your Firebase project credentials. You’ll need it for server-side authorization (more information).

Login in to your Firebase console. Go to Project settings -> Service accounts and then click Generate new private key button.


Generate and save the file. We’ll use it in the next steps.

Spring Boot application

Put generated Firebase Admin SDK JSON file inside your Spring Boot project files (if you don’t have one you can generate it here).

In my case, I created a google folder inside src/main/resources and then copied the generated file there (push-notifications-example-firebase-adminsdk.json).
Then, in my, I added a new key/value pair containing a file path.


Now, we’ll need Firebase dependencies, so let’s add some. I used Maven as a dependency manager.

In my pom.xml dependencies I put an additional dependency:


Now we have to initialize our Firebase application. This is the time to use our app.firebase-configuration-file. I used @Value annotation to inject the path value to the String field.


public class FCMInitializer {

    private String firebaseConfigPath;

    Logger logger = LoggerFactory.getLogger(FCMInitializer.class);

    public void initialize() {
        try {
            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())).build();
            if (FirebaseApp.getApps().isEmpty()) {
      "Firebase application has been initialized");
        } catch (IOException e) {


The initialize() method is being called on application start-up thanks to @PostConstruct annotation.

Sending push notifications

The next step is to prepare our push notifications service class.
But first of all, I separated the following use cases:

  • send push notification to the topic using sample data (defined in
  • send scheduled sample push notification to the topic (every minute)
  • send a push notification with additional data payload (user-defined key/value data object, look at the docs for more information)
  • send push notification without an additional data payload
  • send push notification to a specific user

Sending push notification without data payload example from FCMService class:

public class FCMService {


    public void sendMessageWithoutData(PushNotificationRequest request)
            throws InterruptedException, ExecutionException {
        Message message = getPreconfiguredMessageWithoutData(request);
        String response = sendAndGetResponse(message);"Sent message without data. Topic: " + request.getTopic() + ", " + response);


    private String sendAndGetResponse(Message message) throws InterruptedException, ExecutionException {
        return FirebaseMessaging.getInstance().sendAsync(message).get();

    private AndroidConfig getAndroidConfig(String topic) {
        return AndroidConfig.builder()

    private ApnsConfig getApnsConfig(String topic) {
        return ApnsConfig.builder()

    private Message getPreconfiguredMessageWithoutData(PushNotificationRequest request) {
        return getPreconfiguredMessageBuilder(request).setTopic(request.getTopic())


    private Message.Builder getPreconfiguredMessageBuilder(PushNotificationRequest request) {
        AndroidConfig androidConfig = getAndroidConfig(request.getTopic());
        ApnsConfig apnsConfig = getApnsConfig(request.getTopic());
        return Message.builder()
                        new Notification(request.getTitle(), request.getMessage()));


If you really want to test it, you can try to run the application right now and call the proper methods.

In my case, for clarity purposes, I added another layer – PushNotificationService which will be used directly by PushNotificationController in the further steps.

Let’s take a look at PushNotificationService:


public class PushNotificationService {

    private Map<String, String> defaults;

    private Logger logger = LoggerFactory.getLogger(PushNotificationService.class);
    private FCMService fcmService;

    public PushNotificationService(FCMService fcmService) {
        this.fcmService = fcmService;

    @Scheduled(initialDelay = 60000, fixedDelay = 60000)
    public void sendSamplePushNotification() {
        try {
        } catch (InterruptedException | ExecutionException e) {

    public void sendPushNotification(PushNotificationRequest request) {
        try {
            fcmService.sendMessage(getSamplePayloadData(), request);
        } catch (InterruptedException | ExecutionException e) {

    public void sendPushNotificationWithoutData(PushNotificationRequest request) {
        try {
        } catch (InterruptedException | ExecutionException e) {

    public void sendPushNotificationToToken(PushNotificationRequest request) {
        try {
        } catch (InterruptedException | ExecutionException e) {

    private Map<String, String> getSamplePayloadData() {
        Map<String, String> pushData = new HashMap<>();
        pushData.put("messageId", defaults.get("payloadMessageId"));
        pushData.put("text", defaults.get("payloadData") + " " +;
        return pushData;

    private PushNotificationRequest getSamplePushNotificationRequest() {
        PushNotificationRequest request = new PushNotificationRequest(defaults.get("title"),
        return request;


As you see, we have a @Value annotation again over here.
Why? Because we have a bunch of default values to pass to our methods.

So instead of injecting a single value from properties to a particular String variable, I decided to use Map type for simplicity. It still uses the same @Value annotation.

Again, we store the defaults in So the app.notifications.defaults key looks like this:

app.notifications.defaults={topic: 'common', title: 'Common topic - Hello', message: 'Sending test message \uD83D\uDE42', token: 'ss22t03wz208eg:APA2idkkow223FE_0v5yHxqCLTyxAQafj6nWaqi4QzwZTW004q1PUux63UsFN', payloadMessageId: '123', payloadData: 'Hello. This is payload content.'}

Moreover, you can see we’re using the FCMService directly, passing notifications requests objects to it.

For scheduling, I used @Scheduled annotation with an initial delay of 1min. (initialDelay parameter) and 1min. sending interval (fixedDelay parameter). Remember to annotate your Application class with @EnableScheduling.


Let’s interact with our services and build a controller.

For presentation purposes I exposed my service methods as REST API endpoints in order to send custom, direct messages (to the topic or specific subscriber) with/without data payload or trigger the default notification sending.


public class PushNotificationController {

    private PushNotificationService pushNotificationService;

    public PushNotificationController(PushNotificationService pushNotificationService) {
        this.pushNotificationService = pushNotificationService;

    public ResponseEntity sendNotification(@RequestBody PushNotificationRequest request) {
        return new ResponseEntity<>(new PushNotificationResponse(HttpStatus.OK.value(), "Notification has been sent."), HttpStatus.OK);


    public ResponseEntity sendSampleNotification() {
        return new ResponseEntity<>(new PushNotificationResponse(HttpStatus.OK.value(), "Notification has been sent."), HttpStatus.OK);
} fragment

Test REST endpoints with cURL

Let’s test our endpoints. I used cURL for this task but you can use your favorite HTTP requests tools or write a small client app for this.

  • GET /notification – Trigger sample notification with default values sending
curl -H "Content-Type: application/json" -X GET http://localhost:8080/notification
  • POST /notification/topic – Send a message to a specific topic
curl -d '{"title":"Hello", "message":"The message...", "topic":"contactTopic"}' -H "Content-Type: application/json" -X POST http://localhost:8080/notification/topic
  • POST /notification/token – Send a message to a specific device (with the token)
curl -d '{"title":"Hey you!", "message":"Watch out!", "token":"cct00ebz8eg:APA91bFcTkFE_0Qafj6nWv5yHxqCLTyxAaqi4QzwsFNLP5M9G78X8Z5UMZTW004q1PUux63Ut-1WMGVToMNTdB3ZfO8lCZlc4lGpxm7LBdWfkhaUxdbpQ5xIO5cAb-w9H2dBLNHT7i-U", "topic": ""}' -H "Content-Type: application/json" -X POST http://localhost:8080/notification/token
  • POST /notification/data – Send a message to a specific topic with additional payload data.
    Please note: in this case I took defaults from as sample payload. In your application, you should probably use third-party API data or persistent data from your database.
curl -d '{"title":"Hello", "message":"Data message", "topic":"contactTopic"}' -H "Content-Type: application/json" -X POST http://localhost:8080/notification/data


If succeeded you should receive the following JSON response with code 200:


    "status": 200,
    "message": "Notification has been sent."



Well… If configured properly it just works. I used my Ionic app and Android phone as a client.

Take a look at this screenshot with received notifications:

In this case, the client-side app doesn’t handle additional payload data.

Are you curious about the yellow color of notifications? I set it in NotificationParameter enum along with sound option value (which is default in my case).
See the reference for more additional fields description.


In this post, I covered basic Firebase Cloud Messaging integration with the Spring Boot application. If you’re looking for server-side push notification implementation I think this is the way to go.

As I mentioned before, the fully working example is available on GitHub. If you’re looking for a basic client-side mobile application please take a look at my previous Ionic push notifications app post.

Please note that the provided example was tested with an Android application. Although I provided some basic Apple Push Notification Service (APNS) configuration you have to deal with potential issues when developing an iOS application. If you managed to do it please let me know.

Good luck!


95 thoughts on “Send push notifications from Spring Boot server-side application using FCM”

  1. Thanks for this tutorials, I have followed your steps closely, but i am having an error, this is the error message “FirebaseApp with name [DEFAULT] doesn’t exist. “, i will be glad if you can find time to help me out. Thanks

        1. Hi Brian. You have to include JSON file generated in your Firebase application console.

          But I tested it once again and it’s not necessary to have this particular file in the back-end project. It works just fine without it. It’s important on the client side – for example in the Ionic app.

  2. Thanks for the tutorial, I have followed the steps and placed the firebase-adminsdk json file inside the google folder. I want to send a notification to the specific device. I have Token, Sender ID, Device ID, and FCMToken, but not getting how to use them in the application properties file.

    URL use: http://localhost:8080/notification/token

    app.notifications.defaults={title:’Hey you!’, message:’Watch out!’, token:’dZ2rMLNNOwM:PA91bF3LbFKiXqOVQR8NcvTyT5M4vsxPZLvRPEDevAoEI0m4sNLxA4eyKqJ5g6zJIzbmushrjbmgHxzJsWnkjrhDGiH-gza-yyncN3wnLV2DRhw3gMGxFT_J7FHrl-5wHW7qKWo’, topic: ‘Any’}

    1. Hi Anand. Thanks for your comment.

      First of all, I’m not sure if it’s because of comments formatting but it looks like your quotation marks are invalid.

      You’re using where the valid ones are: ' (single quotation) or " (double quotation mark).

      Please take a look at this fragment where I used my properties:

      In this example I used it to load the defaults into single Map object using @Value annotation.
      You can try to load them into separate String objects as well. Or even, for the test purposes, you can use your FCM values directly.

      Good luck

  3. Hello Rafal,

    I have deployed the spring boot server side app and it runs okay. But the challenges i am having now is the UI. How do I consume the notification. Kindly provide a source code showing how the api is consume and the messages are displayed

    1. Hi Oma. In my case the client side was built with Ionic Framework. Please take a look here for a reference.

      There’s also a link to the GitHub repository. Hope it helps.

  4. Hi,
    Your tutorial is totally good. I have it works too in my localhost. But, when the project was deployed in weblogic server (i’m packaging it to .war), the notification sending action doesn’t work.

    Can you help me what’s wrong with it?

  5. Hello Rafal,

    I have error “java.util.concurrent.ExecutionException: Error while calling FCM backend service”

    I’m use: /notification/token

    Can you help me what’s wrong with it?

  6. Hi,
    I did what you did and got the right JSON answer. But I got this error on the console.

    c.s.d.service.PushNotificationService : Invalid value at ‘’ (TYPE_ENUM), “hıgh”

    Do you know anything about this error? I’ll be glad, if you help me.

    Have a nice day.

  7. Hello Rafal,

    First , thanks a lot for your post it is very helpful,
    i added my .json file but when i tried to send a message i received the below error, i tried to search in Stackoverflow related question but i did not found any answer

    -------------------------------------------------- Error while calling FCM backend service
    ... 29 more
  8. Hi bro I have done all steps which writen below. It seems like as working, service send me response `Notification has been sent` and debugger shows respose contains with message `projects/my-project-name/messages/some-id` but I can’t find this notification on the console. Please help me solve this problem

    1. Hi Eldor 👋

      By `console` do you mean the Firebase console?
      I don’t think it will show you the notifications you’ve sent outside that console.

      If you want to keep track of them, I’d suggest saving them in your back-end application DB.

  9. Hi. By including firebase dependency, google signin verification shows an error :

    java.lang.nosuchmethoderror:;)[b when fcm present

    This error is coming at following line:
    GoogleIdToken googleToken = verifier.verify(requestHeader);

    Can you help me to solve this issue?

  10. Hi @rafal this FCM notifiction tutorial is very helpful to me.please keep posting more about spring technology

    thanks for the post
    Nirav Patel

    1. Hi Nirav, thanks for your comment, I really appreciate it.

      On the blog I’m going to focus on Spring-related technologies in the nearest future, so keep up to date.

      Which aspects of Spring interest you the most?

  11. Hello Rafal,
    Thank you for such a great article. It work very well.
    I am planning to deploy the server app on Heroku.
    My concern is, is it okay to deploy the project with the Firebase Admin SDK Json file with Private Key in resources folder onto Heroku server?

    Thank you in advance for your help

    1. Hi Abdul, thanks for your comment.

      You should put it into the `resources` folder inside your Spring Boot project. Which means in your source code, before building the project. As I presume, on the Heroku you’ll deploy an application that has been already built – which is *.war or *.jar file.

      So don’t worry, as long as you don’t share the file with your private key publically, it’s all okay.
      Firebase integration library needs this file to handle push notification sending.

      Good luck with your deployment

      1. Thank you very much for the reply. On Heroku, I submit my repo and it is build on the Heroku server, which means, I have to push my source files there. I dont know if I can deply *.war or *.jar onto Heroku.

        Thank you again for your reply

        1. Okay Abdul, I understand now. So Heroku does the deploy for you.
          I assume it’s a git repo. So as long as it stays non-public it should be safe and accessible only for you and your project’s collaborators.

          Good luck

          1. Thanks a lot Rafal for clearing my doubts. I appreciate your responses.

  12. Hello Rafal,
    The tutorial is perfect but the thing is after following the steps, when trying to set a specific token and calling the /notification/token page or using the command it does not work giving the following error : Whitelabel Error Page

    This application has no explicit mapping for /error, so you are seeing this as a fallback.
    Sun Mar 08 16:28:55 EET 2020
    There was an unexpected error (type=Method Not Allowed, status=405).
    Request method ‘GET’ not supported
    org.springframework.web.HttpRequestMethodNotSupportedException: Request method ‘GET’ not supported

    1. Hey George.

      Thanks for your comment.
      It looks like something is wrong with your controller class. Make sure if your `RequestMapping`s are done correctly.

      Take care, Rafal

  13. One more thing, can you please guide me how can I send “click_action” with the FCM notification. I want to start activity according to the sent data

    Thank you in advance

    1. Hey Abdul, I have never tried it but it looks like you just have to put another key-value pair into push notification data map.

      Like this:

      pushData.put(“click_action”, “action_to_be_performed”);

  14. Hi Rafal,

    Do u know if we can call push notification of SDK via proxy , and if yes how?

    Thanks in advance

    1. Hi Marios.

      What do you mean by proxy? It sounds more like a network layer configuration related issue?

      Thanks for your comment


  15. Thank you your post !

    I have a one issues. When I call api push message. Firebase return response “c.t.f.s.FirebaseCloudMessageService : SenderId mismatch”. Can you help me ? . Thank you very much.

    1. Hi Tuan

      Thanks for your comment.

      Please check if you have your Firebase Admin SDK JSON file in place or try to regenerate it.

      Hope it helps

  16. Hey I used this tutorial and has been working great for me… until last week. Does this still work? Now when trying to run this I get this error: 401 Unauthorized
    Unexpected HTTP response with status: 401; body: null

    1. Hey Jacob

      Please try to recheck your Firebase Admin SDK JSON files.

      It definitely looks like a Google API connection error.

      Take care!

  17. Hi, Rafal.

    Excellent example! I have a doubt. How can I send specials characters in push notification body? I’m triying to send notifications in spanish. For example: áéíóú

  18. Can you explain how you have connected the client side application on the phone for this particular application in firebase? It is very confusing.

    1. Hi Nivedita!
      Thanks for your comment.

      In this text I described the back-end side only.
      That’s correct.

      The mobile application I used for receiving push notifications is described here. I built it using Ionic Framework.

      Take care

      1. Okay. Thank You for your help!

        Further, I was wondering if you could tell me if it is possible to use this to connect a web application that we are making using React JS instead of the Ionic Framework App.

        1. Sure thing.

          But please note that you have to integrate your client with a particular Firebase application. Not with the back-end app, I described in this post.
          Here we just send a request to the FCM and let the Firebase do all the magic with the message delivery.

          I have no experience with React but you try to can search for the terms like ‘FCM + React’.
          For example:

  19. Hi Rafal,
    I want to read resources/google/service-acount-file.json file from database using pojo.
    FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())).build();
    At the place of firebaseConfigPath, I want to use string JSON.
    How can I use it?

  20. What if I want to add an action link and an image to the notification request. How would it look like in that case ? Can anyone please help me with this?

  21. Hi Rafal,
    I got this error java.lang.NoSuchMethodError:;)J
    on this line
    String response = FirebaseMessaging.getInstance().send(message);

    Can you help me to solve this error

  22. This works perfectly for iOS as well.
    No configuration changes required as the APNS integration is taken care at the FCM level.

  23. Hello.
    I have followed your tutorial, but I got some trouble.
    When I want to send notification with “POST /notification/token”, in postman response is success but when I check running service forim springboot, I found error “ : senderId mismatch”.

    my body postman :
    “title”:”Hey you!”,
    “message”:”Watch out!”,
    “topic”: “”

    Could you explain it? what’s wrong.
    thank you.

    1. I have solved it.
      Thank you 🙂
      on’t stop for writting, because it is useful for us.
      God bless you 🙂

      1. Hello Septian!

        Sorry for the necro, but how did you solve this? I am having this issue right now and can’t seem to find a solution.

        For clarification, I have regenerated the admin SDK JSON file twice and confirmed that it is correct and can be read during execution.

        What is more strange is that I can get the message to deliver to the destination if I run this locally. But when I try to run this on the server, I get the SenderId mismatch
        error message.

        Any help is appreciated. Thanks in advance.

  24. Hi,
    I got this spring boot code from your github. I am successfully able to run your code as well and getting response as {200,’message sent sucessfully’}. But not sure ,not receiving notification on my client application. private keys is also correctly downloaded.
    I am able to send message from FCM to application. but when I am trying it from back end i.e from your code not getting notification.

    Here I am not able to figure about, when I am sending message to FCM, where I can check in FCM that back end has sent message.
    Can you help me to figure out this?

  25. Hi Rafal,

    This is excellent stuff man.. saved my day.. Thanks a lot for sharing. Keep up the good work man. Appreciate your effort.

  26. Hi Rafal,

    Apart from my previous comment, It looks like since you already setting the APNS config to the Message object, if I have given the apple token id this should work seamlessly right ? I have tested this with sample android app in android studio with the help of Firebase assistant on android studio. this works smoothly once integrated with your spring boot app. Also, I have attached some additional data map and get that too through my sample android. Am using your token endpoint. Feels like this should work for apple like this too… Do you have any thoughts? Please shed some light. Thanks and Keep up the good work.

    1. Hi Sam 👋
      Thanks for your support.

      Unfortunately, I didn’t try it with iOS yet.

      But please take look at the comment from Rajesh Subramanian under this blog post. He confirms that it works seamlessly for iOS apps 👍

      Take care 👋

  27. Can you help me with ios notifications? i get 200 and no notifications appear, only if i send them from firebase console

    1. Hi Iván 👋
      Unfortunately, I didn’t try it with iOS yet.

      But please take look at the comment from Rajesh Subramanian under this blog post. He confirms that it works for iOS as well.

  28. Hey , i’ve this error when i try to post a request : Error while calling FCM backend service

    iam using linux !

  29. I was following the tutorial and getting the below error.

    java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist
  30. I have already implemented the push notification service and I want to save all notifications in my database so the application user can delete notifications from the app.
    My app currently has around 100,000 users and creating a single database record for each user is a very tedious process.
    Could you please suggest a proper way for this ?

    1. Hi Praaven 👋

      I guess using topics is not the case here (because I suppose you want to serve every user separately).
      So maybe try to introduce a new property to your `User` class that will hold a current Firebase token.
      Then, you can update it every time when user device will register in Firebase.

      Does it make sense for you?

  31. hey plz help me with push-notifications-example-firebase-adminsdk.json sample format. i mean i am not getting what to write in this file.
    i am having api_key, database id and all but how to write it in json file plz hepl me on priority.

  32. as i imported your code but getting error as bellow:

    2020-10-13 04:02:41.807 ERROR 4260 --- [ scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task.
    java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist.
    at ~[firebase-admin-6.8.1.jar:na]
    at ~[firebase-admin-6.8.1.jar:na]
    at ~[firebase-admin-6.8.1.jar:na]
    at net.mestwin.fcmpushnotifications.firebase.FCMService.sendAndGetResponse( ~[classes/:na]
    at net.mestwin.fcmpushnotifications.firebase.FCMService.sendMessageWithoutData( ~[classes/:na]
    at net.mestwin.fcmpushnotifications.service.PushNotificationService.sendSamplePushNotification( ~[classes/:na]
    at sun.reflect.GeneratedMethodAccessor32.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_231]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_231]
    at ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
    at ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
    at java.util.concurrent.Executors$ Source) [na:1.8.0_231]
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source) [na:1.8.0_231]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) [na:1.8.0_231]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ Source) [na:1.8.0_231]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_231]
    at java.util.concurrent.ThreadPoolExecutor$ Source) [na:1.8.0_231]
    at Source) [na:1.8.0_231]
  33. Hi Rafal,
    I got the below error from the local server. could you please help me to find out what I am missing?

    ————— Error while calling FCM backend service

    1. Hi Navas, recently I had to integrate push notifications again with another application and it worked like a charm.

      Did you copy the Firebase JSON file into your `resources`?

  34. Thank you very much for the Tutorial.

    I got an error in getPreconfiguredMessageBuilder method in . It says ,

    ‘Notification(’ has private access in ‘’

    Can someone please help me to solve this.

    1. Instead of using new Notification you need to pass Notification.builder.

      Old code:
      return Message.builder()
      new Notification(request.getTitle(),

      New code:
      Message.Builder builder = Message.builder()
      return builder;

      I hope this helps you in some way.

      1. Fair point Barbara, if we’re using builders let’s use it everywhere.

        Thanks for pointing it out 🙂

        I’ll update it soon.

        Take care 👋

  35. Hi, I have error with this: import net.mestwin.fcmpushnotifications.model.PushNotificationRequest;

    It’s not found it in FCMService. Can you help me?

  36. Hello! Thank you so much for the tutorial, i have followed through till the end but am stuck at the testing part. I would like to ask when testing the endpoint for: POST /notification/token, how do i retrieve the token of my device? Thank you for the help!

Leave a Reply

Your email address will not be published.