老板说:明天来加班写个FCM消息推送功能……

老板说:明天来加班写个FCM消息推送功能……前言最近在开发一款国际版的 APP 项目中需要支持客户端消息推送 自己实现肯定是不可能的 需要寻找第三方的 SDK 在做技术调研的时候决定使用 google 的 FCM 框架来实现 有个缺点就是大陆是接收不到的 fq 可以

欢迎大家来到IT世界,在知识的湖畔探索吧!

前言

最近在开发一款国际版的APP,项目中需要支持客户端消息推送,自己实现肯定是不可能的,需要寻找第三方的SDK。在做技术调研的时候决定使用google的FCM框架来实现,有个缺点就是大陆是接收不到的(fq可以)。那么本章就给大家分享一下如何基于Spring Boot集成Firebase实现FCM消息推送功能。

必要条件

开发

第一步:申请开发者账号

地址:https://console.firebase.google.com/

第二步:添加一个项目

如下图所示,添加一个项目:

老板说:明天来加班写个FCM消息推送功能......



欢迎大家来到IT世界,在知识的湖畔探索吧!

老板说:明天来加班写个FCM消息推送功能......

老板说:明天来加班写个FCM消息推送功能......

第三步:下载google-services.json文件

点击左上角——设置(图标)——项目设置,点击google-services.json下载,如下图所示:

老板说:明天来加班写个FCM消息推送功能......

将下载好的文件放到Spring Boot项目的resources目录下,例如:

老板说:明天来加班写个FCM消息推送功能......

存放目录

第四步:集成Firebase

pom引用firebase,要fq才能下载,如果没有条件就需要手动导入下载好的jar包。

<dependency> <groupId>com.google.firebase</groupId> <artifactId>firebase-admin</artifactId> <version>6.5.0</version> </dependency>

欢迎大家来到IT世界,在知识的湖畔探索吧!

第五步:编写FCM推送消息请求实体

这里只是做了个发送消息的简单封装实体,方便数据传输:

欢迎大家来到IT世界,在知识的湖畔探索吧!import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.List; / * * 功能描述: FCM推送消息请求实体 * @auther: IT实战联盟Line * @date: 2019年11月25日09:54:51 */ @NoArgsConstructor @Data @ApiModel(value = "FCM推送消息请求实体") public class FCMSendMessageReqDTO implements Serializable { private static final long serialVersionUID = L; @ApiModelProperty(value = "消息标题" , required = true) private String title; @ApiModelProperty(value = "消息内容" , required = true) private String body; @ApiModelProperty(value = "用户token集合" , required = true) private String tokens; @ApiModelProperty(value = "主题" , required = false) private String topic; }

第六步:编写FCM推送消息工具类

该工具类支持单个和批量推送,这里批量采用的是给主题推。

import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import com.google.auth.oauth2.GoogleCredentials; import java.util.concurrent.ConcurrentHashMap; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.AndroidConfig; import com.google.firebase.messaging.AndroidConfig.Builder; import com.google.firebase.messaging.AndroidNotification; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.Message; import com.google.firebase.messaging.Notification; import com.google.firebase.messaging.TopicManagementResponse; / * @Auther: IT实战联盟Line * @Date: 2019-11-23 14:02 * @Description: Google_FireBase推送工具类 */ public class FireBaseUtil { //存放多个实例的Map private static Map<String, FirebaseApp> firebaseAppMap = new ConcurrentHashMap<>(); //获取AndroidConfig.Builder对象 private static com.google.firebase.messaging.AndroidConfig.Builder androidConfigBuilder=AndroidConfig.builder(); //获取AndroidNotification.Builder对象 private static AndroidNotification.Builder androidNotifiBuilder=AndroidNotification.builder(); / * 判断SDK是否初始化 * @param appName * @return */ public static boolean isInit(String appName) { return firebaseAppMap.get(appName) != null; } / * 初始化SDK * @param jsonPath JSON路径 * @param dataUrl firebase数据库 * @param appName APP名字 * @throws IOException */ public static void initSDK(String jsonPath, String dataUrl,String appName) throws IOException { InputStream serviceAccount = Thread.currentThread().getContextClassLoader().getResourceAsStream(jsonPath); FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount)) .setDatabaseUrl(dataUrl).build(); //初始化firebaseApp FirebaseApp firebaseApp = FirebaseApp.initializeApp(options); //存放 firebaseAppMap.put(appName,firebaseApp); } / * 单设备推送 * @param appName 应用的名字 * @param token 注册token * @param title 推送题目 * @param bady 推送内容 * @return * @throws IOException * @throws FirebaseMessagingException */ public static void pushSingle(String appName, String token, String title, String body) throws IOException, FirebaseMessagingException{ //获取实例 FirebaseApp firebaseApp = firebaseAppMap.get(appName); //实例为空的情况 if (firebaseApp == null) { return; } //构建消息内容 Message message = Message.builder().setNotification(new Notification(title,body)) .setToken(token) .build(); //发送后,返回messageID String response = FirebaseMessaging.getInstance(firebaseApp).send(message); System.out.println("单个设备推送成功 : "+response); } / * 给设备订阅主题 * @param appName 应用的名字 * @param tokens 设备的token,最大1000个 * @param topic 要添加的主题 * @return * @throws FirebaseMessagingException * @throws IOException */ public static void registrationTopic(String appName, List<String> tokens, String topic) throws FirebaseMessagingException, IOException { //获取实例 FirebaseApp firebaseApp = firebaseAppMap.get(appName); //实例不存在的情况 if(firebaseApp == null) { return; } //订阅,返回主题管理结果对象。 TopicManagementResponse response = FirebaseMessaging.getInstance(firebaseApp).subscribeToTopic(tokens, topic); System.out.println("添加设备主题,成功:" + response.getSuccessCount() + ",失败:" + response.getFailureCount()); } / * 按主题推送 * @param appName 应用的名字 * @param topic 主题的名字 * @param title 消息题目 * @param body 消息体 * @return * @throws FirebaseMessagingException * @throws IOException */ public static void sendTopicMes(String appName, String topic, String title, String body) throws FirebaseMessagingException, IOException { //获取实例 FirebaseApp firebaseApp = firebaseAppMap.get(appName); //实例不存在的情况 if(firebaseApp == null) { return; } //构建消息 Message message = Message.builder() .setNotification(new Notification(title,body)) .setTopic(topic) .build(); //发送后,返回messageID String response = FirebaseMessaging.getInstance(firebaseApp).send(message); System.out.println("主题推送成功: " + response); } }

第七步:编写FCM推送Controller

一共两个Controller,单推和群推。

欢迎大家来到IT世界,在知识的湖畔探索吧!import com.google.firebase.messaging.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import java.io.*; import java.util.*; @Api(value = "FireBase", description = "FireBase") @RequestMapping("/") @RestController @Slf4j public class FireBaseController { //渠道名字,也是APP的名字 public static String appName = "FCM后台新增的项目名称"; @ApiOperation(value = "批量FireBase推送", notes = "批量FireBase推送") @ApiImplicitParam(name = "fcmSendMessageReqDTO", value = "{\"title\":\"测试标题\",\"body\":\"测试内容\",\"tokens\":\"1,2\"}") @PostMapping(value = "/pushFireBaseAll", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public void pushFireBaseAll(@RequestBody FCMSendMessageReqDTO fcmSendMessageReqDTO) { log.info("进入批量FireBase推送 pushFireBaseAll:[{}]", fcmSendMessageReqDTO.toString()); //添加tokens List<String> tokens = Arrays.asList(fcmSendMessageReqDTO.getTokens().split(",")); //设置Java代理,端口号是代理软件开放的端口,这个很重要。 System.setProperty("proxyHost", "127.0.0.1"); System.setProperty("proxyPort", "8081"); //如果FirebaseApp没有初始化 if (!FireBaseUtil.isInit(appName)) { String jsonPath = "fcm/xxxx-firebase-adminsdk.json"; String dataUrl = "https://xxxx.firebaseio.com/"; //初始化FirebaseApp try { FireBaseUtil.initSDK(jsonPath, dataUrl, appName); FireBaseUtil.registrationTopic(appName, tokens, fcmSendMessageReqDTO.getTopic()); //设置主题 FireBaseUtil.sendTopicMes(appName, fcmSendMessageReqDTO.getTopic(), fcmSendMessageReqDTO.getTitle(), fcmSendMessageReqDTO.getBody()); //按主题推送 } catch (Exception e) { e.printStackTrace(); } } else { log.info("如果FirebaseApp已经初始化"); try { FireBaseUtil.registrationTopic(appName, tokens, fcmSendMessageReqDTO.getTopic()); //设置主题 FireBaseUtil.sendTopicMes(appName, fcmSendMessageReqDTO.getTopic(), fcmSendMessageReqDTO.getTitle(), fcmSendMessageReqDTO.getBody()); //按主题推送 } catch (IOException e) { e.printStackTrace(); } catch (FirebaseMessagingException e) { e.printStackTrace(); } } } @ApiOperation(value = "FireBase推送", notes = "FireBase推送") @ApiImplicitParam(name = "fcmSendMessageReqDTO", value = "{\"title\":\"测试标题\",\"body\":\"测试内容\",\"tokens\":\"1\"}") @PostMapping(value = "/pushFireBase", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public void pushFireBase(@RequestBody FCMSendMessageReqDTO fcmSendMessageReqDTO) { log.info("进入批量FireBase推送 pushFireBaseAll:[{}]", fcmSendMessageReqDTO.toString()); //添加tokens List<String> tokens = Arrays.asList(fcmSendMessageReqDTO.getTokens().split(",")); //设置Java代理,端口号是代理软件开放的端口,这个很重要。 System.setProperty("proxyHost", "127.0.0.1"); System.setProperty("proxyPort", "8081"); //如果FirebaseApp没有初始化 if (!FireBaseUtil.isInit(appName)) { String jsonPath = "fcm/xxxx-firebase-adminsdk.json"; String dataUrl = "https://xxxx.firebaseio.com/"; //初始化FirebaseApp try { FireBaseUtil.initSDK(jsonPath, dataUrl, appName); FireBaseUtil.pushSingle(appName, tokens.get(0), fcmSendMessageReqDTO.getTitle(), fcmSendMessageReqDTO.getBody()); //单推 } catch (Exception e) { e.printStackTrace(); } } else { log.info("如果FirebaseApp已经初始化"); try { FireBaseUtil.pushSingle(appName, tokens.get(0), fcmSendMessageReqDTO.getTitle(), fcmSendMessageReqDTO.getBody()); //单推 } catch (IOException e) { e.printStackTrace(); } catch (FirebaseMessagingException e) { e.printStackTrace(); } } } }

Spring Boot 项目中集成了swagger ,小伙伴在使用的时候可以去掉。代码是没问题的,都已经测试过。

总结

1、一定要确认网络是否可以FQ,如果不行是访问不了firebase service的。否则会报以下错误,如图所示:

老板说:明天来加班写个FCM消息推送功能......

A、应用“杀死”后基本收不到消息。 B、Android8 系统不管应用是否可用都出现收不到消息问题。 有资源的小伙伴可以多测试集中机型哦。

5、设备必须是android4.0以上,Google Play Services 必须是 11.2.0以上版本(这个没有测试,拥有的资源基本都是6以上)。

老板说:明天来加班写个FCM消息推送功能......

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/98461.html

(0)
上一篇 19小时前
下一篇 19小时前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信