Firebase

Send FCM message from Android

Pinterest LinkedIn Tumblr

In this article, I’ll show how we can send an FCM message from an android device. in other words, you can say, will tell send android firebase push notifications device to device. How to do that, Let’s get started.

Create a new application.

Let’s open the Android Studio and create a new project with the default template.

Add libraries in app-level build.gradle file

In this example, we are using followings libraries for making network call

  //  Add these line in your project
  implementation 'com.squareup.retrofit2:retrofit:2.7.1'
  implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
  implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.1'
  implementation "com.squareup.okhttp3:logging-interceptor:4.3.1"
Add Base URL and FCM SERVER KEY in build config field your project build.gradle

Let add below variables inside gradle file. Now create a project on firebase. After that Replace FCM_SERVER_KEY ID with your server id.

buildTypes {
    debug {
      buildConfigField("String", "FCM_BASE_URL", "\"https://fcm.googleapis.com/\"")
      buildConfigField("String", "FCM_SERVER_KEY", "\"xxxxxxxxxxxxxxxxxxxxxxxx\"")
    }
    release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
  }
Add Internet permission manifest

For sending the notification, we will need to internet permission, let’s open the android manifest and add below permission.

  <uses-permission android:name="android.permission.INTERNET" />
Write a network API client

Let’s create a network provider class, In this class, we are using Retrofit and OKHHTP client for debugging.

package com.sendinganotificationmessage;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
  public static NotificationApiService getApiService() {
    return new Retrofit.Builder()
        .baseUrl(BuildConfig.FCM_BASE_URL)
        .client(provideClient())
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(NotificationApiService.class);
  }

  private static OkHttpClient provideClient() {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    return new OkHttpClient.Builder().addInterceptor(interceptor).addInterceptor(chain -> {
      Request request = chain.request();
      return chain.proceed(request);
    }).build();
  }
}
Now create notification API service
package com.sendinganotificationmessage;

import com.google.gson.JsonObject;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;

public interface NotificationApiService {

  @Headers({
      "Authorization: key="+BuildConfig.FCM_SERVER_KEY ,
      "Content-Type: application/json"
  })
  @POST("fcm/send")
  Call<JsonObject> sendNotification(@Body JsonObject payload);
}
Modify your main activity layout file

For taking input from the user will update the layout file that contains a few text input item for capturing device token, title and message

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    >

  <com.google.android.material.textfield.TextInputLayout
      android:id="@+id/textInputLayout5"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginTop="16dp"
      android:layout_marginEnd="16dp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      >

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/textReceiverToken"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Receiver FCM Token"
        android:maxLines="1"
        android:text="fnn3DoqhPPM:APA91bHBDfHv0YC5Mpncu1Got_d28-FIRDEH1gwXj27HGB5_Qbn49cyE7M2zeKijq4FEuApsW6-lEbNGrIGwhhERKTTtGxLvz8Q5xvF_x1QlX3Um8DiKsnYjqeEMySrjAhQNeI8Kot7S"

        />
  </com.google.android.material.textfield.TextInputLayout>
  <com.google.android.material.textfield.TextInputLayout
      android:id="@+id/textInputLayout"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginTop="8dp"
      android:layout_marginEnd="16dp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textInputLayout5"
      >

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/textTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Title"
        />
  </com.google.android.material.textfield.TextInputLayout>
  <com.google.android.material.textfield.TextInputLayout
      android:id="@+id/textInputLayout2"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginTop="8dp"
      android:layout_marginEnd="16dp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textInputLayout"
      >

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/textMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Message"/>
  </com.google.android.material.textfield.TextInputLayout>
  <TextView
      android:id="@+id/textView"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginTop="16dp"
      android:text="Additional data you want to pass (In key-value pair)"
      android:textColor="@color/colorAccent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textInputLayout2"
      />
  <com.google.android.material.textfield.TextInputLayout
      android:id="@+id/textInputLayout3"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginTop="16dp"
      app:layout_constraintEnd_toStartOf="@+id/textInputLayout4"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textView"
      >

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/textKey"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Key"
        />
  </com.google.android.material.textfield.TextInputLayout>
  <com.google.android.material.textfield.TextInputLayout
      android:id="@+id/textInputLayout4"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginEnd="16dp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toEndOf="@+id/textInputLayout3"
      app:layout_constraintTop_toTopOf="@+id/textInputLayout3"
      >

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/textValue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Value"
        />
  </com.google.android.material.textfield.TextInputLayout>
  <Button
      android:id="@+id/buttonSendNotification"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="16dp"
      android:layout_marginTop="24dp"
      android:layout_marginEnd="16dp"
      android:background="@color/colorAccent"
      android:text="Send Notification"
      android:textColor="#ffffff"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textInputLayout3"
      />


</androidx.constraintlayout.widget.ConstraintLayout>
Let’s move to main activity files

Let’s bind the views using id. As you see below code we taking the input from users and send notification using the retrofit client. We taking input like title, messaging and FCM token.

package com.sendinganotificationmessage;

import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.google.gson.JsonObject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {
  Button sendNotificationButton;
  TextInputEditText receiverFdmId;
  TextInputEditText title;
  TextInputEditText message;
  TextInputEditText key;
  TextInputEditText value;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initViews();
    sendNotificationButton.setOnClickListener(view -> {
      if (validateInput()) {
        JsonObject payload = buildNotificationPayload();
        // send notification to receiver ID
        ApiClient.getApiService().sendNotification(payload).enqueue(
            new Callback<JsonObject>() {
              @Override
              public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                if (response.isSuccessful()) {
                  Toast.makeText(MainActivity.this, "Notification send successful",
                      Toast.LENGTH_LONG).show();
                }
              }

              @Override public void onFailure(Call<JsonObject> call, Throwable t) {

              }
            });
      }
    });
  }

  private JsonObject buildNotificationPayload() {
    // compose notification json payload
    JsonObject payload = new JsonObject();
    payload.addProperty("to", receiverFdmId.getText().toString());

    // compose data payload here
    JsonObject data = new JsonObject();
    data.addProperty("title", title.getText().toString());
    data.addProperty("message", message.getText().toString());
    data.addProperty(key.getText().toString(), value.getText().toString());
    // add data payload
    payload.add("data", data);
    return payload;
  }

  private boolean validateInput() {
    if (receiverFdmId.getText().toString().isEmpty()
        || title.getText().toString().isEmpty()
        || message.getText().toString().isEmpty()
        || key.getText().toString().isEmpty()
        || value.getText().toString().isEmpty()) {
      Toast.makeText(this, "Please fill all field correctly", Toast.LENGTH_LONG).show();
      return false;
    }
    return true;
  }

  private void initViews() {
    sendNotificationButton = findViewById(R.id.buttonSendNotification);
    receiverFdmId = findViewById(R.id.textReceiverToken);
    title = findViewById(R.id.textTitle);
    message = findViewById(R.id.textMessage);
    key = findViewById(R.id.textKey);
    value = findViewById(R.id.textValue);
  }
}

Let’s run the project and see your app will run and up. Lets put device token, title and message, finally tap on send.

Conclusion

In this android app tutorial, We have learned the implementation of sending FCM message from android. I hope it’s helpful for you, let’s do a favor for me, share this post with all your friends.

Get Solution Code

Keep in touch

If you want to keep in touch so let’s follow me on Facebook or Subscribe to us. Still, if you have any queries please put your comment below.

Requisition

Please read all Firebase articles in single place.

3 Comments

Write A Comment