[JAVA] [FCM] Implementation of message transmission using FCM + Spring boot

Overview

Send a message to your Android device using Google's FCM service. Send messages using a server API that supports HTTP v1 so that you can receive push notifications on your Android device.

Preparation

Prepare a Firebase Console account and log in.

Enter the project name (any name) Analytics and billing regions: Japan Press Create Project

Issuing a certificate and obtaining a SHA-1 key

keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore

You will be prompted to enter the password.

android

I was able to issue it at.

Paste the SHA-1 key output from the console when debugging.keystore is issued to the debug signature certificate SHA-1 (optional).

Press Register App.

Create a new project in Android Studio (Empty Activity)

Download google-services.json and place it directly under the Android Studio app.

Added the following services to AndroidManifest.xml.

        <service
            android:name="com.example.shosakaguchi.notifytest.FcmMessagingService"
            >
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <service
            android:name="com.example.shosakaguchi.notifytest.FcmInstanceIdService"
            >
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>

Added the following dependencies to the app build.gradle.

    api 'com.google.firebase:firebase-core:+'
    api 'com.google.firebase:firebase-messaging:+'
    api 'com.fasterxml.jackson.core:jackson-databind:+'
    api 'com.google.firebase:firebase-auth:+'

Add the following dependencies to the project build.gradle + apply google-services.

dependencies {
api "com.google.firebase:firebase-messaging:10.2.4"
}
apply plugin: 'com.google.gms.google-services'

Rebuild the project.

Generate the following class in Android Studio.

A class that inherits FirebaseMessagingService (the contents are empty)

Arbitrary class name extends FirebaseMessagingService

Class inheriting FirebaseInstanceIdService

Arbitrary class name extends FirebaseInstanceIdService
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

    }

Added code to get token and terminal token in MainActivity.java.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //get device token
        FcmInstanceIdService sv = new FcmInstanceIdService();
        sv.onTokenRefresh();
    }
}

Run the project on the device that receives the push notification.

Make a note of the token that appears in the Logcat console on Android Studio.

Implementation of server API (Spring boot)

Create a new Spring Project using STS on Eclipse.

Add the following dependency to build.gradle.

	compile('com.fasterxml.jackson.core:jackson-databind:+')
	compile('com.google.firebase:firebase-admin:+')

From the Gradle task, hit buildDependents.

Prepare the following information from the settings page of the Firabase console page. -POST destination endpoint URL https://fcm.googleapis.com/v1/projects/全般ページのプロジェクトID/messages:send"

・ Private key Click on the service account from the Firabase console settings page Press "Generate New Private Key" on the Firebase Admin SDK tab. Honyara.json will be downloaded, so place it in the appropriate resource folder of your Spring project.

Implementation of initialize method

	public static void initializeToken() throws IOException{
		FileInputStream serviceAccount = new FileInputStream("Downloaded private key path");

		FirebaseOptions options = new FirebaseOptions.Builder()
		    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
		    .setDatabaseUrl("https://Project ID.firebaseio.com")
		    .build();

		FirebaseApp.initializeApp(options);
	}

Implementation of access token acquisition method

	public static  String getAccessToken() throws IOException {
		  GoogleCredential googleCredential = GoogleCredential
		      .fromStream(new FileInputStream("Downloaded private key path"))
		      .createScoped(Arrays.asList("https://www.googleapis.com/auth/firebase.messaging"
		    		  ));
		  googleCredential.refreshToken();
		  return googleCredential.getAccessToken();
	}

For the time being, in order to send a message when the server application is executed, the main class should be processed.

TestProject.java

	public static void main(String[] args) {
		SpringApplication.run(PushAppTestApplication.class, args);
		System.out.println("start");

		try {
		//initialize firebasio
		initializeToken();

		//post param create
		URL url = new URL(Endpoint URL of the POST destination);
		HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
		httpURLConnection.setRequestMethod("POST");
		httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
//		System.out.println("token" + getAccessToken());
		httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
		httpURLConnection.setDoOutput(true);

		httpURLConnection.connect();

		OutputStream out = httpURLConnection.getOutputStream();
		PrintStream ps = new PrintStream(out);
		ps.print(BODY part of request message JSON (described later));
		ps.close();

		//return response output
		InputStream is = httpURLConnection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String s;
	    while ((s = reader.readLine()) != null) {
			System.out.println(httpURLConnection.getResponseMessage() + httpURLConnection.getResponseCode());
	        }
			reader.close();
			httpURLConnection.disconnect();
			} catch(Exception e) {
				e.printStackTrace();
		}
		System.out.println("end");
	}

BODY part of request message JSON

	private final static String reqJson = "{\n" +
			"  \"message\":{\n" +
			"    \"token\" : \"Tokens appearing in the Logcat console on Android Studio",\n" +
			"    \"notification\" : {\n" +
			"      \"body\" : \"Test message\",\n" +
			"      \"title\" : \"Test title\",\n" +
			"      }\n" +
			"   }\n" +
			"}";

That's all for implementation.

This time, I mainly implemented sending push notifications to a single terminal. In practice, it is necessary to think carefully about the assumption when sending to multiple terminals, the assumption of transmission time (cron batch etc.), the mechanism to send the device token to the server and storing it.

From the next time, I would like to introduce those HowTos and examples.

Thank you for your hard work.

Recommended Posts

[FCM] Implementation of message transmission using FCM + Spring boot
Going out of message (Spring boot)
Asynchronization of message transmission
[Java / Spring Boot] Spring security ④ --Implementation of login process
[Java / Spring Boot] Spring security ⑤ --Implementation of logout processing
Try using Spring Boot Security
Spring Boot validation message changes
Minimal customization of Spring Boot error page (implementation of ErrorController interface)
Execution of initial processing using Spring Boot Command Line Runner
Memorandum of understanding when Spring Boot 1.5.10 → Spring Boot 2.0.0
Spring Boot Tutorial Using Spring Security Authentication
Implementation of validation using regular expressions
[Spring Boot] Role of each class
Message cooperation started with Spring Boot
I want to control the default error message of Spring Boot
Unknown error in line 1 of pom.xml when using Spring Boot in Eclipse
[Android] Implementation of side-scrolling ListView using RecyclerView
Implementation of user authentication function using devise (2)
Try using Spring Boot with VS Code
Implementation of user authentication function using devise (1)
WebMvcConfigurer Memorandum of Understanding for Spring Boot 2.0 (Spring 5)
Implementation of tabs using TabLayout and ViewPager
Implementation of user authentication function using devise (3)
Asynchronous processing with Spring Boot using @Async
How to split Spring Boot message file
[Rails] Implementation of search function using gem's ransack
[Rails 6] Implementation of inquiry function using Action Mailer
Summary of what I learned about Spring Boot
[Rails] Implementation of image enlargement function using lightbox2
Create a Spring Boot application using IntelliJ IDEA
The story of raising Spring Boot 1.5 series to 2.1 series
Let's check the feel of Spring Boot + Swagger 2.0
Various correspondence table of Spring Framework and Spring Boot
When @Transactional of Spring Boot does not work
[JQuery] Implementation procedure of AutoComplete function [Java / Spring]
[Rails] Implementation of batch processing using whenever (gem)
[Rails] Implementation of PV number ranking using impressionist
[Rails] Implementation of image slide show using Bootstrap 3
Apply Twitter Bootstrap 4 to Spring Boot 2 using Webjars
[Verification] Comparison of Spring Boot vs Micronaut boot speed
CSRF countermeasure policy and implementation example in REST application using "Spring Boot" + "EXT JS"
Challenge Spring Boot
Implementation of GKAccessPoint
Let's make a circuit breaker for back-end service using Actuator of Spring Boot (Part 1)
Spring Boot Form
Spring Boot Memorandum
gae + spring boot
Implementation of Google Sign-In using Google OAuth 2.0 authentication (server edition)
Create a portfolio app using Java and Spring Boot
Testing JPA entities and repositories using Spring Boot @DataJpaTest
Specify the encoding of static resources in Spring Boot
Try using DI container with Laravel and Spring Boot
[Note] Configuration file when using Logback with Spring Boot
Message cooperation started with Spring Boot Apache Kafka edition
I checked asynchronous execution of queries in Spring Boot 1.5.9
A memorandum of addiction to Spring Boot2 x Doma2
Try using OpenID Connect with Keycloak (Spring Boot application)
Access the built-in h2db of spring boot with jdbcTemplate
05. I tried to stub the source of Spring Boot
[JUnit 5 compatible] Write a test using JUnit 5 with Spring boot 2.2, 2.3
I tried to reduce the capacity of Spring Boot