Firebase Cloud Messaging for push notifications From Spring Boot
Let’s learn how to send push notifications to iOS and Android mobile devices via Firebase cloud messaging(FCM) service using Spring Boot for example.
Mobile notifications play a major role in user engagement. With Firebase’s new SDK for Java, sending Firebase push notifications from a Spring Boot application got a lot easier.
Table of contents
1) Setup Firebase messaging dependency
To include the Firebase-SDK you need to add the following maven dependency to your project.
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>7.0.0</version>
</dependency>
Code language: HTML, XML (xml)
2) Get the Service Account Private Key from FCM Console
The next thing you have to do is to generate a service-account.json. For this open the Service Accounts in FCM console and click Generate Private Key.
This will download a file in the form of <firebase-project>-firebase-adminsdk-<hash>.json
. Save this file src/java/resources
as firebase-service-account.json
.
3) Configure Spring Bean for Push notification
In our spring boot application, Let’s create an object for FirebaseMessaging
and register it as a bean. This bean will be used to send notifications.
@Bean
FirebaseMessaging firebaseMessaging() throws IOException {
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(new ClassPathResource("firebase-service-account.json").getInputStream());
FirebaseOptions firebaseOptions = FirebaseOptions
.builder()
.setCredentials(googleCredentials)
.build();
FirebaseApp app = FirebaseApp.initializeApp(firebaseOptions, "my-app");
return FirebaseMessaging.getInstance(app);
}
Code language: Java (java)
Here new ClassPathResource("firebase-service-account.json").getInputStream()
is an easier way to create an InputStream for a file in classpath. With this, we created a FirebaseApp
object from which we got our FirebaseMessaging
instance.
4) Write a Push notification Service
I wrote a simple FirebaseMessagingService
by using the bean that we just created. In a very basic use case, the class would look like this.
@Service
public class FirebaseMessagingService {
private final FirebaseMessaging firebaseMessaging;
public FirebaseMessagingService(FirebaseMessaging firebaseMessaging) {
this.firebaseMessaging = firebaseMessaging;
}
public String sendNotification(Note note, String token) throws FirebaseMessagingException {
Notification notification = Notification
.builder()
.setTitle(note.getSubject())
.setBody(note.getContent())
.build();
Message message = Message
.builder()
.setToken(token)
.setNotification(notification)
.putAllData(note.getData())
.build();
return firebaseMessaging.send(message);
}
}
Code language: Java (java)
4.1) Understand how Firebase Library works
Here, The Notification
object captures what Title and Body to show on the mobile notification.
The Message
object has multiple builder methods to deal with various scenarios.
- Send a message to a specific recipient by using
setToken(String)
or you can send it to anyone who is subscribed to a topic by usingsetTopic(String)
- Pass additional data to the mobile applications using
putData(String, String)
orputAllData(Map<String, String>)
. - Customize options specific to Android, iOS, and web clients using the below builder methods respectively.
setAndroidConfig()
setApnsConfig()
setWebpushConfig()
- Each method has a set of builder methods to back their configuration further.
Once you have created a message
object with appropriate values, you can call firebaseMessaging.send(Message)
to submit the request. The method will return a String which represents the message ID that was sent during the API call. There is no need to store this value. Note that there can be a FirebaseMessagingException
if there is an error while processing the message while sending. So make sure you handle it.
5) Write a Test Controller
Let’s write a simple test API call.
@Data
public class Note {
private String subject;
private String content;
private Map<String, String> data;
private String image;
}
/*******************************/
@RequestMapping("/send-notification")
@ResponseBody
public String sendNotification(@RequestBody Note note,
@RequestParam String token) throws FirebaseMessagingException {
return firebaseService.sendNotification(note, token);
}
Code language: Java (java)
6) Verifying push notification from Spring Boot
A simple curl command with a sample post date yields the following result.
$ curl -X POST "http://localhost:8080/send-notification?topic=gold" \
-H "Content-Type: application/json" \
-d '{
"subject": "some subject",
"content": "Some long content",
"image": "https://somedomain.com/example.jpg",
"data": {
"key1": "Value 1",
"key2": "Value 2",
"key3": "Value 3",
"key4": "Value 4"
}
}'
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 53
Date: Thu, 10 Sep 2020 14:21:50 GMT
Keep-Alive: timeout=60
Connection: keep-alive
projects/spring-demo/messages/2282285117414704507
Code language: Bash (bash)
Notice how the response is projects/spring-demo/messages/2282285117414704507
which is the message ID of the fired message to FCM. We can use this message ID to debug the business logic on the client side.
Note that in the GitHub example, You will have to replace the
firebase-service-account.json
downloaded from your FCM project.
7) Summary & Sample Code
We learned how to send Firebase cloud messaging push notifications using Spring Boot with an example.
You can play with the demo project here in this GitHub repository. Also, If you liked this article, please check out the following write-ups.
Very Nice and helpful article.
This is a very good cloud messaging tutorial.
Can you please help me to send same notification with Image and Time Scheduling ?
When I set Online Image URL then Image Popup in notification but when I set local Path then notification done but image didn’t.
So please help me out.
And
Also help me to schedule the notification
Like I send notification now but schedule time is 6:00 PM so my API has sent the notification at now(Means at time of calling API ) but your mobile should receive notification at 6:00 PM (Scheduling Time).
the
setImage()
method only takes an URL accessible over internet. But it’s worth trying a file URL like “file://some/path/to/your/local/file/on/android/image.jpg”. But that specific file should already exist on that device. Also, You need to have permissions to read files from storage. I guess that goes without saying.And for the scheduling part, I am not aware if FCM does this out of the box.
But you could use quartz scheduler to send notifications at a specific time.
Very Nice and helpful article.
This is a very good cloud messaging tutorial.
Can you please help me to send “firebase in app” message from Spring Boot ?
please send any article, resource and any other help/guidance to “[email protected]”.
The “In-App-Messaging” Feature is poorly named. It is technically not a messaging solution, But a campaign solution. Like for a popup or a hover notification. For in-app messaging, you can only create campaigns from the Firebase Console. There is no Java SDK that you can use to create these campaigns.
Hi Raja,
thanks for clear post, it is very usefull. I have a question, do you know if there is a limit on how much devices can receive the notification sent by a topic? For multicast there is the limit of 500 devices, with topic instead?
Unlike multicast, Topic doesn’t have any practical limit. All users subscribed to a topic will receive that specific notification. The catch here is that the messages will be somewhat slower. More on this at https://firebase.google.com/docs/cloud-messaging/android/topic-messaging
Hallo,
it is workeing, I get this rsponse “projects/notifikation-server/messages/8608202705779338491”, but I did not recieve any notification on my android phone.
can you help me.
Thanks
First, make sure your app is ready and configured to take messages.
Also, the example primarily uses TOPIC based notification. If you want to send it to a specific user, you need to use the registration token using the
setToken(String)
instead.