MoinMoin Logo
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Navigation

  • Start
  • Sitemap

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

Revision 9 as of 2021-01-18 16:28:43
  • Java
  • Spring
  • SpringBoot
  • FCMSendPush

FCMSendPush

Firebase Cloud Messaging example

Structure

   1 .
   2 ├── build.sh
   3 ├── pom.xml
   4 ├── run.sh
   5 ├── src
   6 │   └── main
   7 │       ├── java
   8 │       │   └── hello
   9 │       │       ├── Application.java
  10 │       │       ├── Data.java
  11 │       │       ├── Message.java
  12 │       │       ├── Notification.java
  13 │       │       ├── PushMessage.java
  14 │       │       ├── PushResponse.java
  15 │       │       └── SendPushController.java
  16 │       └── resources
  17 │           ├── application.properties
  18 │           ├── logback-spring.xml
  19 │           └── templates
  20 │               ├── sendpushform.html
  21 │               └── sendpush.html

build.sh

   1 #!/bin/sh
   2 mvn clean install

run.sh

   1 #!/bin/sh
   2 # /tmp/outpush.log logback-spring.xml
   3 # /tmp/greet.log logback-spring.xml
   4 java -Dfilelog=/tmp/outpush.log -jar target/test-spring-boot-push-0.1.0.jar

pom.xml

   1 <?xml version="1.0" encoding="UTF-8"?>
   2 <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">
   3     <modelVersion>4.0.0</modelVersion>
   4     <groupId>hello</groupId>
   5     <artifactId>test-spring-boot-push</artifactId>
   6     <version>0.1.0</version>
   7     <parent>
   8         <groupId>org.springframework.boot</groupId>
   9         <artifactId>spring-boot-starter-parent</artifactId>
  10         <version>2.1.6.RELEASE</version>
  11     </parent>
  12     <dependencies>
  13         <dependency>
  14             <groupId>org.springframework.boot</groupId>
  15             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  16         </dependency>
  17         <dependency>
  18             <groupId>org.springframework.boot</groupId>
  19             <artifactId>spring-boot-starter-web</artifactId>
  20         </dependency>
  21         <dependency>
  22             <groupId>com.google.code.gson</groupId>
  23             <artifactId>gson</artifactId>
  24             <version>2.8.6</version>
  25             <scope>compile</scope>
  26         </dependency>
  27     </dependencies>
  28     <properties>
  29         <start-class>hello.Application</start-class>
  30     </properties>
  31     <build>
  32         <plugins>
  33             <plugin>
  34                 <groupId>org.springframework.boot</groupId>
  35                 <artifactId>spring-boot-maven-plugin</artifactId>
  36             </plugin>
  37         </plugins>
  38     </build>
  39     <repositories>
  40         <repository>
  41             <id>spring-milestone</id>
  42             <url>http://repo.spring.io/libs-release</url>
  43         </repository>
  44     </repositories>
  45     <pluginRepositories>
  46         <pluginRepository>
  47             <id>spring-milestone</id>
  48             <url>http://repo.spring.io/libs-release</url>
  49         </pluginRepository>
  50     </pluginRepositories>
  51 </project>

src/main/java/hello/Application.java

   1 package hello;
   2 
   3 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
   4 import org.springframework.boot.SpringApplication;
   5 import org.springframework.context.annotation.ComponentScan;
   6 import org.slf4j.Logger;
   7 import org.slf4j.LoggerFactory;
   8 
   9 @ComponentScan //scans for @Component beans 
  10 @EnableAutoConfiguration
  11 public class Application {
  12     private static Logger logger;
  13 
  14     public static void main(String[] args) {
  15         logger = LoggerFactory.getLogger(Application.class);
  16         logger.info("Starting application");
  17         SpringApplication.run(Application.class, args);
  18     }
  19 }

src/main/java/hello/Message.java

   1 package hello;
   2 
   3 public class Message {
   4     private String message_id;
   5 
   6     public String getMessage_id() {
   7         return message_id;
   8     }
   9 
  10     public void setMessage_id(String message_id) {
  11         this.message_id = message_id;
  12     }
  13 }

src/main/java/hello/PushMessage.java

   1 package hello;
   2 
   3 public class PushMessage {
   4     private String to;
   5     private Data data;
   6     private Notification notification;
   7 
   8     public PushMessage() {
   9     }
  10 
  11     public Notification getNotification() {
  12         return notification;
  13     }
  14 
  15     public void setNotification(Notification notification) {
  16         this.notification = notification;
  17     }
  18 
  19     public Data getData() {
  20         return data;
  21     }
  22 
  23     public void setData(Data data) {
  24         this.data = data;
  25     }
  26 
  27     public String getTo() {
  28         return to;
  29     }
  30 
  31     public void setTo(String to) {
  32         this.to = to;
  33     }
  34 }

src/main/java/hello/SendPushController.java

   1 package hello;
   2 
   3 import org.springframework.core.env.Environment;
   4 import org.springframework.http.HttpHeaders;
   5 import org.springframework.http.HttpMethod;
   6 import org.springframework.stereotype.Controller;
   7 import org.springframework.web.bind.annotation.RequestMapping;
   8 import org.springframework.web.bind.annotation.RequestMethod;
   9 import org.springframework.web.bind.annotation.RequestParam;
  10 import org.springframework.ui.Model;
  11 import org.springframework.util.MimeTypeUtils;
  12 
  13 import java.io.BufferedReader;
  14 import java.io.InputStreamReader;
  15 import java.io.OutputStream;
  16 import java.net.HttpURLConnection;
  17 import java.net.URL;
  18 import com.google.gson.Gson;
  19 import org.slf4j.Logger;
  20 import org.slf4j.LoggerFactory;
  21 
  22 @Controller
  23 public class SendPushController {
  24     private static final String UTF_8 = "utf-8";
  25     private final Logger logger = LoggerFactory.getLogger(SendPushController.class);
  26     private Environment env;
  27     private String fcmKey;
  28     private String fcmSendUrl;
  29 
  30     public SendPushController(Environment env) {
  31         logger.debug("SendPush controller created.");
  32         this.env = env;
  33         this.fcmKey = this.env.getProperty("fcm.key");
  34         this.fcmSendUrl = this.env.getProperty("fcm.send.url");
  35     }
  36 
  37     @RequestMapping("/sendpush")
  38     // http://localhost:8181/sendpush
  39     public String sendpush(Model model) {
  40         logger.info("Greeting sendpush called.");
  41         model.addAttribute("title", "Send push");
  42         return "sendpush";
  43     }
  44 
  45     @RequestMapping(value = "/sendpushform", method = RequestMethod.POST)
  46     public String sendpushform(@RequestParam("dev_token") String devToken,
  47             @RequestParam("message_title") String messageTitle, @RequestParam("message") String message, Model model) {
  48         logger.info("Greeting sendpushform called.");
  49         model.addAttribute("devToken", devToken);
  50         model.addAttribute("message", message);
  51         model.addAttribute("messageTitle", messageTitle);
  52         model.addAttribute("title", "Send push result");
  53 
  54         try {
  55             URL url = new URL(this.fcmSendUrl);
  56             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  57             connection.setRequestMethod(HttpMethod.POST.name());
  58 
  59             connection.setRequestProperty(HttpHeaders.CONTENT_TYPE,
  60                     MimeTypeUtils.APPLICATION_JSON_VALUE + "; " + UTF_8);
  61             connection.setRequestProperty(HttpHeaders.ACCEPT, MimeTypeUtils.APPLICATION_JSON_VALUE);
  62             connection.setRequestProperty(HttpHeaders.AUTHORIZATION, "key=" + this.fcmKey);
  63             connection.setDoOutput(true);
  64 
  65             PushMessage push = new PushMessage();
  66             push.setTo(devToken);
  67             Data data = new Data();
  68             data.setBody(message);
  69             data.setTitle(messageTitle);
  70             push.setData(data);
  71 
  72             Notification notification = new Notification();
  73             notification.setBody(message);
  74             notification.setTitle(messageTitle);
  75             push.setNotification(notification);
  76             Gson gson = new Gson();
  77             String payload = gson.toJson(push);
  78             try (OutputStream os = connection.getOutputStream()) {
  79                 byte[] input = payload.getBytes(UTF_8);
  80                 os.write(input, 0, input.length);
  81             }
  82 
  83             try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), UTF_8))) {
  84                 StringBuilder response = new StringBuilder();
  85                 String responseLine = null;
  86                 while ((responseLine = br.readLine()) != null) {
  87                     response.append(responseLine.trim());
  88                 }
  89                 PushResponse pr = gson.fromJson(response.toString(), PushResponse.class);
  90                 model.addAttribute("prSuccess", pr.getSuccess());
  91                 model.addAttribute("multicastId", pr.getMulticast_id());
  92             }
  93 
  94         } catch (Exception e) {
  95             e.printStackTrace();
  96         }
  97 
  98         return "sendpushform";
  99     }

src/main/java/hello/Data.java

   1 package hello;
   2 
   3 public class Data {
   4     private String title;
   5     private String body;
   6 
   7     public Data() {
   8     }
   9 
  10     public String getBody() {
  11         return body;
  12     }
  13 
  14     public void setBody(String body) {
  15         this.body = body;
  16     }
  17 
  18     public String getTitle() {
  19         return title;
  20     }
  21 
  22     public void setTitle(String title) {
  23         this.title = title;
  24     }
  25 }

src/main/java/hello/Notification.java

   1 package hello;
   2 
   3 public class Notification {
   4     private String title;
   5     private String body;
   6 
   7     public Notification() {
   8     }
   9 
  10     public String getBody() {
  11         return body;
  12     }
  13 
  14     public void setBody(String body) {
  15         this.body = body;
  16     }
  17 
  18     public String getTitle() {
  19         return title;
  20     }
  21 
  22     public void setTitle(String title) {
  23         this.title = title;
  24     }
  25 }

src/main/java/hello/PushResponse.java

   1 package hello;
   2 
   3 public class PushResponse {
   4 
   5     private long multicast_id;
   6     private long success;
   7     private long failure;
   8     private long canonical_ids;
   9     private Message[] results;
  10 
  11     public Message[] getResults() {
  12         return results;
  13     }
  14 
  15     public long getCanonical_ids() {
  16         return canonical_ids;
  17     }
  18 
  19     public void setCanonical_ids(long canonical_ids) {
  20         this.canonical_ids = canonical_ids;
  21     }
  22 
  23     public long getFailure() {
  24         return failure;
  25     }
  26 
  27     public void setFailure(long failure) {
  28         this.failure = failure;
  29     }
  30 
  31     public long getSuccess() {
  32         return success;
  33     }
  34 
  35     public void setSuccess(long success) {
  36         this.success = success;
  37     }
  38 
  39     public long getMulticast_id() {
  40         return multicast_id;
  41     }
  42 
  43     public void setMulticast_id(long multicast_id) {
  44         this.multicast_id = multicast_id;
  45     }
  46 
  47     public void setResults(Message[] results) {
  48         this.results = results;
  49     }
  50 }

src/main/resources/application.properties

   1 server.port=8181
   2 fcm.key=AAAA(...)
   3 fcm.send.url=https://fcm.googleapis.com/fcm/send

src/main/resources/logback-spring.xml

   1 <?xml version="1.0" encoding="UTF-8"?>
   2 <configuration>
   3 <!--
   4     <include resource="org/springframework/boot/logging/logback/defaults.xml" />
   5     <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
   6     <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
   7 -->
   8     <!-- override spring logback default behaviour -->
   9     <appender name="FILE" class="ch.qos.logback.core.FileAppender">
  10         <file>${filelog}</file>
  11         <encoder>
  12                 <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
  13         </encoder>
  14     </appender>
  15     <appender name="GREETFILE" class="ch.qos.logback.core.FileAppender">
  16         <file>/tmp/greet.log</file>
  17         <encoder>
  18                 <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
  19         </encoder>
  20     </appender>
  21     <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  22         <layout class="ch.qos.logback.classic.PatternLayout">
  23                 <Pattern>%yellow(%date{ISO8601}) %green([%thread]) %highlight(%-5level) %cyan(%logger{35}) - %white(%msg%n) </Pattern>
  24         </layout>
  25     </appender>
  26     <root level="INFO">
  27         <appender-ref ref="FILE" />
  28         <appender-ref ref="CONSOLE"/>
  29     </root>
  30     <logger name="hello.GreetingController" level="debug" additivity="false">
  31         <appender-ref ref="GREETFILE"/>
  32         <appender-ref ref="CONSOLE" />
  33     </logger>
  34 </configuration> 

src/main/resources/templates/sendpushform.html

   1 <!DOCTYPE HTML>
   2 <html>
   3 <head>
   4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
   5     <meta name="viewport" content="width=device-width, initial-scale=1" />
   6     <title>Send push result</title>
   7     <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
   8     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"         integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous" />
   9     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
  10         integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
  11         crossorigin="anonymous"></script>
  12 </head>
  13 <body>
  14     <div class="container">
  15         <div class="row">
  16             <div class="col-2"></div>
  17             <div class="col-8">
  18                 <div class="card text-white bg-success">
  19                     <div class="card-header">
  20                         <h1 th:text="${title}"></h1>
  21                     </div>
  22                     <div class="card-body bg-white" style="color:black;">
  23                         <h1 class="card-title">Dev token</h1>
  24                         <p class="card-text" th:text="${devToken}"></p>
  25                         <h1 class="card-title">Message title</h1>
  26                         <p class="card-text" th:text="${messageTitle}"></p>
  27                         <h1 class="card-title">Message</h1>
  28                         <p class="card-text" th:text="${message}"></p>
  29                         <h1 class="card-title">Push success</h1>
  30                         <p class="card-text" th:text="${prSuccess}"></p>
  31                         <h1 class="card-title">Push multicast Id</h1>
  32                         <p class="card-text" th:text="${multicastId}"></p>
  33                     </div>
  34                     <a href="/sendpush" class="btn btn-lg btn-primary btn-block">Go back</a>
  35                 </div>
  36             </div>
  37             <div class="col-2"></div>
  38         </div>
  39     </div>
  40 </body>
  41 </html>

src/main/resources/templates/sendpush.html

   1 <!DOCTYPE HTML>
   2 <html xmlns:th="http://www.thymeleaf.org">
   3 <head>
   4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
   5     <meta name="viewport" content="width=device-width, initial-scale=1" />
   6     <title>Send push</title>
   7     <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
   8     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
   9         integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous" />
  10     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
  11         integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
  12         crossorigin="anonymous"></script>
  13 </head>
  14 <body>
  15     <div class="container">
  16         <div class="row">
  17             <div class="col-2"></div>
  18             <div class="col-8">
  19                 <div class="card text-white bg-primary">
  20                     <div class="card-header">
  21                         <h1 th:text="${title}"></h1>
  22                     </div>
  23                     <div class="card-body bg-white" style="color:black;">
  24                         <form action="sendpushform" method="POST">
  25                             <input type="text" name="dev_token" class="form-control" placeholder="dev token" />
  26                             <br />
  27                             <input type="text" name="message_title" class="form-control" placeholder="message title" />
  28                             <br />
  29                             <input type="text" name="message" class="form-control" placeholder="message" />
  30                             <br />
  31                             <input type="submit" value="Send push notification"
  32                                 class="btn btn-lg btn-primary btn-block" />
  33                         </form>
  34                     </div>
  35                 </div>
  36             </div>
  37             <div class="col-2"></div>
  38         </div>
  39     </div>
  40 </body>
  41 </html>
  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01