= FCMSendPush =
Firebase Cloud Messaging example

== Structure ==
{{{#!highlight bash
.
├── build.sh
├── pom.xml
├── run.sh
├── src
│   └── main
│       ├── java
│       │   └── hello
│       │       ├── Application.java
│       │       ├── Data.java
│       │       ├── Message.java
│       │       ├── Notification.java
│       │       ├── PushMessage.java
│       │       ├── PushResponse.java
│       │       └── SendPushController.java
│       └── resources
│           ├── application.properties
│           ├── logback-spring.xml
│           └── templates
│               ├── sendpushform.html
│               └── sendpush.html
}}}

== build.sh ==
{{{#!highlight bash
#!/bin/sh
mvn clean install
}}}

== run.sh ==
{{{#!highlight bash
#!/bin/sh
# /tmp/outpush.log logback-spring.xml
# /tmp/greet.log logback-spring.xml
java -Dfilelog=/tmp/outpush.log -jar target/test-spring-boot-push-0.1.0.jar
}}}

== pom.xml ==
{{{#!highlight xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>hello</groupId>
    <artifactId>test-spring-boot-push</artifactId>
    <version>0.1.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <properties>
        <start-class>hello.Application</start-class>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestone</id>
            <url>http://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestone</id>
            <url>http://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>
}}}

== Application.java ==
{{{#!highlight java
package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ComponentScan //scans for @Component beans 
@EnableAutoConfiguration
public class Application {
    private static Logger logger;

    public static void main(String[] args) {
        logger = LoggerFactory.getLogger(Application.class);
        logger.info("Starting application");
        SpringApplication.run(Application.class, args);
    }
}
}}}

== Message.java ==
{{{#!highlight java
package hello;

public class Message {
    private String message_id;

    public String getMessage_id() {
        return message_id;
    }

    public void setMessage_id(String message_id) {
        this.message_id = message_id;
    }
}
}}}

== PushMessage.java ==
{{{#!highlight java
package hello;

public class PushMessage {
    private String to;
    private Data data;
    private Notification notification;

    public PushMessage() {
    }

    public Notification getNotification() {
        return notification;
    }

    public void setNotification(Notification notification) {
        this.notification = notification;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }
}
}}}

== SendPushController.java ==
{{{#!highlight java
package hello;

import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.ui.Model;
import org.springframework.util.MimeTypeUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Controller
public class SendPushController {
    private static final String UTF_8 = "utf-8";
    private final Logger logger = LoggerFactory.getLogger(SendPushController.class);
    private Environment env;
    private String fcmKey;
    private String fcmSendUrl;

    public SendPushController(Environment env) {
        logger.debug("SendPush controller created.");
        this.env = env;
        this.fcmKey = this.env.getProperty("fcm.key");
        this.fcmSendUrl = this.env.getProperty("fcm.send.url");
    }

    @RequestMapping("/sendpush")
    // http://localhost:8181/sendpush
    public String sendpush(Model model) {
        logger.info("Greeting sendpush called.");
        model.addAttribute("title", "Send push");
        return "sendpush";
    }

    @RequestMapping(value = "/sendpushform", method = RequestMethod.POST)
    public String sendpushform(@RequestParam("dev_token") String devToken,
            @RequestParam("message_title") String messageTitle, @RequestParam("message") String message, Model model) {
        logger.info("Greeting sendpushform called.");
        model.addAttribute("devToken", devToken);
        model.addAttribute("message", message);
        model.addAttribute("messageTitle", messageTitle);
        model.addAttribute("title", "Send push result");

        try {
            URL url = new URL(this.fcmSendUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod(HttpMethod.POST.name());

            connection.setRequestProperty(HttpHeaders.CONTENT_TYPE,
                    MimeTypeUtils.APPLICATION_JSON_VALUE + "; " + UTF_8);
            connection.setRequestProperty(HttpHeaders.ACCEPT, MimeTypeUtils.APPLICATION_JSON_VALUE);
            connection.setRequestProperty(HttpHeaders.AUTHORIZATION, "key=" + this.fcmKey);
            connection.setDoOutput(true);

            PushMessage push = new PushMessage();
            push.setTo(devToken);
            Data data = new Data();
            data.setBody(message);
            data.setTitle(messageTitle);
            push.setData(data);

            Notification notification = new Notification();
            notification.setBody(message);
            notification.setTitle(messageTitle);
            push.setNotification(notification);
            Gson gson = new Gson();
            String payload = gson.toJson(push);
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = payload.getBytes(UTF_8);
                os.write(input, 0, input.length);
            }

            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), UTF_8))) {
                StringBuilder response = new StringBuilder();
                String responseLine = null;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                PushResponse pr = gson.fromJson(response.toString(), PushResponse.class);
                model.addAttribute("prSuccess", pr.getSuccess());
                model.addAttribute("multicastId", pr.getMulticast_id());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return "sendpushform";
    }
}}}

== Data.java ==
{{{#!highlight java
package hello;

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

    public Data() {
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
}}}

== Notification.java ==
{{{#!highlight java
package hello;

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

    public Notification() {
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
}}}

== PushResponse.java ==
{{{#!highlight java
package hello;

public class PushResponse {

    private long multicast_id;
    private long success;
    private long failure;
    private long canonical_ids;
    private Message[] results;

    public Message[] getResults() {
        return results;
    }

    public long getCanonical_ids() {
        return canonical_ids;
    }

    public void setCanonical_ids(long canonical_ids) {
        this.canonical_ids = canonical_ids;
    }

    public long getFailure() {
        return failure;
    }

    public void setFailure(long failure) {
        this.failure = failure;
    }

    public long getSuccess() {
        return success;
    }

    public void setSuccess(long success) {
        this.success = success;
    }

    public long getMulticast_id() {
        return multicast_id;
    }

    public void setMulticast_id(long multicast_id) {
        this.multicast_id = multicast_id;
    }

    public void setResults(Message[] results) {
        this.results = results;
    }
}
}}}