Integrating Push Notifications with Firebase Java API

Integrating Push Notifications with Firebase Java API

·

13 min read

Firebase is one of the most versatile app development platforms available in the market right now. What started out as an independent company was acquired by Google back in 2014, and since then they haven’t had to look back.

This article was originally posted at: https://quod.ai/post/integrating-push-notifications-with-firebase-java-api

Today, Firebase boasts of 18 different products that cater to a variety of needs for both mobile and web applications. Today, we will be looking at how we can implement push notifications in our Android app using Firebase Cloud Messaging, popularly known as FCM. This tutorial assumes basic knowledge of Android programming and Firebase. You can head over to Firebase Console to learn how you can set your project up.

Sneak Peek

Here is a little preview of the app that we will be building. We have two apps, one from where the push notifications will be sent and the other where they will be received. The sender sends the notification to a particular topic and all the subscribers of that particular topic will receive the notification. This is also an implementation of the popular pub-sub design pattern in messaging.

The sender has two fields, the title and the body for the message and a button to send the message to the topic. We have created a topic called ‘deals’ that will alert users every time there is a new offer.

The receiving app was made using boilerplate Android code, but it does have the listener subscribed to the topic which allows it to receive notifications each time a message is sent to the topic.

Sender Code

Let’s take a look at the sender side code first. This is the part that is slightly complicated. We need a few things before we get started. First, head over to the Firebase Console and get the Server Key from the Cloud Messaging tab from Project Settings. This will be needed to authenticate your requests and it needs to be added to the header in the request.

Constants File

 public class Constants {
    public static final String SERVER_KEY = "ENTER YOUR SERVER KEY HERE";
    public static final String BASE_URL = "https://fcm.googleapis.com";
    public static final String CONTENT_TYPE = "application/json";
}

View Constants.java in context at Quod AI

Line 1-5: Create a class called Constants and store all the constant values in that. We have the server key, content-type, and the base URL for Firebase Cloud Messaging here. Remember to replace the server key with the value from your Firebase Console.

Model Classes

public class Notification {
    private String title;
    private String body;

    public Notification(String title, String body) {
        this.title = title;
        this.body = body;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getBody() {
        return body;
    }
    public void setBody(String body) {
        this.body = body;
    }
}

View Notification.java in context at Quod AI

Line 1-21: Now, we will create all the model classes. The one required for the notification data and the one for the response. The Notification class given below has the fields, title, and body, along with a constructor and getters/setters. This is pretty straightforward Java code.

public class PushNotification {
    private Notification notification;
    private String to;

    public PushNotification(Notification notification, String to) {
        this.notification = notification;
        this.to = to;
    }
    public PushNotification(Notification data) {
        this.notification = data;
    }
    public Notification getNotification() {
        return notification;
    }
    public void setNotification(Notification data) {
        this.notification = data;
    }
    public String getTo() {
        return to;
    }
    public void setTo(String recipient) {
        this.to = recipient;
    }
}

View PushNotification.java in context at Quod AI

Line 1-24: Next, we have the PushNotification class, which is the actual class that we will be using the push to the topic. Here, we have a field of the class Notification and a string field ‘to’, which denotes the recipient or the topic to which we want to push the message to.


We will now create the interface for the API call. We will be using the Retrofit library in Android to make the API calls. Retrofit is a lightweight and very easy-to-use HTTP client available for Android and Java. All you need to start using it is to add the dependency in the build.gradle file. You can read more about it on their official website given above, to get a better picture of the library. It is always a good practice to read the documentation whenever using a library for your application.

Let’s take a closer look at the NotificationAPI interface.

public interface NotificationAPI {
    @Headers({"Authorization: key=" + Constants.SERVER_KEY, "Content-Type:" + Constants.CONTENT_TYPE})
    @POST("fcm/send")
    Call postNotification(@Body PushNotification data);
}

View NotificationAPI.java in context at Quod AI

Line 1-5: Let’s go line by line. The first line @Headers, overrides the default headers and adds the server key that we got before, and sets the content-type as application/json. @Post annotation denotes that this would be a post request and the value inside the brackets show the endpoint. We then have the actual method name that returns a Response (defined above) object when we pass the PushNotiifacation object in the body to the server.

Putting it all together in the MainActivity

public static final String TOPIC = "/topics/deals";


Button sendButton = findViewById(R.id.send);
EditText titleText = findViewById(R.id.title);
EditText contentText = findViewById(R.id.content);


sendButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        String title = titleText.getText().toString();
        String content = contentText.getText().toString();

        if(!title.isEmpty() && !content.isEmpty()){
            Notification message = new Notification(title, content);
            PushNotification data = new PushNotification(message, TOPIC);
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constants.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            NotificationAPI apiService =
                    retrofit.create(NotificationAPI.class);
            Call call = apiService.postNotification(data);
            call.enqueue(new Callback() {
                @Override
                public void onResponse(Call call, retrofit2.Response response) {
                    if (!response.isSuccessful()) {
                        Log.d(TAG, String.valueOf(response.code()));
                        return;
                    }
                    titleText.setText("");
                    contentText.setText("");
                    Toast.makeText(MainActivity.this, "Message Pushed", Toast.LENGTH_SHORT).show();
                }
                @Override
                public void onFailure(Call call, Throwable t) {
                    Log.d(TAG, t.getMessage());

View MainActivity.java in context at Quod AI

Line 1: We have created a topic called ‘deals’ in our code, and it is considered good practice to prefix it with the word ‘topics’.

Line 3-5: We need to first retrieve all the text fields and the send button to use it within the app. The id is mentioned in the XML design code, and findViewById, as the name suggests, is used to get components from the corresponding activity based on the id.

Line 7-8: We will now set an onClickListener on the button, and the rest of the logic required for the program is written within this listener.

Line 9-12: Once the button is clicked, we retrieve the values inside the text fields. This is then used to construct the object that we need to send to the topic.

Line 15-18: Next, we create the Retrofit instance that will be used to make the API call. We set the base URL from our Constants file, set a converter factory (Gson in this case), to convert from JSON to Java POJOs and vice versa.

Line 20-21: We then create an instance of our NotificationsAPI service passing it into the Retrofit instance we created just now.

Line 22-36: When making a Retrofit API call, we can use the enqueue method to asynchronously denote to the user once a response has been received. In our case, we will get a Toast saying that the message has been pushed. If there is a failure, the Toast would show the exception.

Receiver Code

FirebaseMessaging.getInstance().subscribeToTopic(TOPIC)
.addOnCompleteListener(new OnCompleteListener() {
    @Override
    public void onComplete(@NonNull Task task) {
        String msg = ("Subscribed");
        if (!task.isSuccessful()) {
            msg = "Couldn't subscribe to topic";
        }
        Log.d(TAG, msg);
        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
    }
});

View MainActivity (Receiver).java in context at Quod AI

Line 1-12: The receiver is basically an empty Android app, that is subscribed to a topic. It listens in on the topic that we have mentioned and once there is a new message, the listener is triggered and a notification is created using the payload. Inside the MainActivity, the only thing that we need to do is to subscribe to the topic that we created earlier. If everything is successful, we just display a message saying “Subscribed”, otherwise “Couldn’t subscribe to topic”.

Service Class

    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getNotification().getBody());
        }
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }
        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle(remoteMessage.getNotification().getTitle())
                .setContentText(remoteMessage.getNotification().getBody())
                .setSmallIcon(R.mipmap.ic_launcher)
                .build();
        NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
        manager.notify(123, notification);

View MyFirebaseMessagingService.java in context at Quod AI

Line 4: Now, to create the service class. This is a class that extends the FirebaseMessagingService class. We need to override the onMessageReceived method to trigger the notification.

Line 6-10: If the message size is greater than 0 and if the notification field is not null, we create a new notification. The notification title and contents are retrieved from the message that was intercepted by the listener.

Line 12-16: We can also use custom icons in the notifications, but we have used the app icon itself for the notification as well.

Line 17-18: Finally, we use the NotificationManagerCompat to get the application context and push the notification to the screen.

Make something big!

This is just the starting of what you can do with push notifications on Android. Firebase Cloud Messaging is so easy to get started with but complex functionalities like pub-sub messaging that you just saw now are often overlooked. Imagine creating an app that can send push notifications to users based on their vicinity to restaurants about the deals running that day. The possibilities are endless!

https://github.com/QuodAI/tutorial-push-notifications-with-firebase-api-v2