##參考資源 Firebase 雲消息傳遞官網 com.google.firebase.messagingAPI這個連接要FQ firebase推送後臺接入--海外APP推送 fcm google 推送 java 服務端集成前端
##什麼是FCM? 本篇文章主要講實現,概念大略介紹一會兒啦! 推送服務在國內有不少服務商,可是若是是作海外 App ,推薦仍是使用 Google 本身的推送服務,畢竟海外經常使用的手機型號,都是有 Google 服務的。Google 的推送服務,之前叫作 GCM(Google Cloud Message)。而自從 Google 將 Firebase 收購以後,就將推送服務併到 Firebase 的一項服務中了,如今叫作 FCM。 ##FCM推送消息類型java
通知消息包含一組預約義的用戶可見的鍵。與其相對,數據消息只包含用戶定義的自定義鍵值對。通知消息能夠包含可選數據有效負載。這兩種消息類型的有效負載上限均爲 4KB,但從 Firebase 控制檯發送>消息時除外,在那種狀況下,系統會強制執行 1024 個字符的限制。android
##編寫Java推送功能前的準備 ####第一條:獲取Android或者IOS程序在firebase上申請的json。這個json去前端工程師哪裏要,這個必須有! ####第二條:獲取firebase上面Android或者IOS程序的數據庫,這個也得去前端工程師要!數據庫
https://telecomm-76736ei.firebaseio.com/ 長得樣式和上面差很少 ####第三條:得到一個有效的token,這個也得去前端工程師要! e1v12xfHs3g:APA91bFExfQRg1h4AZc3GqLHxW4ohe3D7Ca0xvGMJkSbY3qe9yXf4Xe10c1O4fHJ2I。 獲取有效token的時候樓主可吃過大虧哦,注意裏面的「:」經常被轉義位「%3A」,大家要一萬個當心。 ####第四條:你的電腦能FQ,由於這是發送到Google服務器的。國內是屏蔽訪問國外網絡請求的,若是你想FQ能夠找我,我能夠幫你! ####第五條,添加依賴,沒有下面的log4j依賴會報錯。json
<dependency> <groupId>com.google.firebase</groupId> <artifactId>firebase-admin</artifactId> <version>6.5.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency>
##Java代碼api
import java.io.FileInputStream; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.google.auth.oauth2.GoogleCredentials; 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; /** * Google_FireBase推送工具類 * @author Feiqs * */ 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 { FileInputStream serviceAccount = new FileInputStream(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 tokens 設備的token,最大1000個 * @param topic 取消的主題 * @return * @throws FirebaseMessagingException * @throws IOException */ public static void cancelTopic(String appName, List<String> tokens, String topic) throws FirebaseMessagingException, IOException { //獲取實例 FirebaseApp firebaseApp = firebaseAppMap.get(appName); //實例不存在的狀況 if(firebaseApp == null) { return; } //取消訂閱,返回主題管理結果對象。 TopicManagementResponse response = FirebaseMessaging.getInstance(firebaseApp).unsubscribeFromTopic(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); } /** * 單條Android設備推送消息(和pushSingle方法幾乎沒有區別) * @param appName 應用的名字 * @param token 註冊token * @param title 推送題目 * @param bady 推送內容 * @throws FirebaseMessagingException */ public static void pushSingleToAndroid(String appName, String token, String title, String body) throws FirebaseMessagingException { //獲取實例 FirebaseApp firebaseApp = firebaseAppMap.get(appName); //實例爲空的狀況 if (firebaseApp == null) { return; } androidConfigBuilder.setRestrictedPackageName("io.telecomm.telecomm"); androidNotifiBuilder.setColor("#55BEB7");// 設置消息通知顏色 androidNotifiBuilder.setIcon("https://www.shiku.co/images/favicon.png");// 設置消息圖標 androidNotifiBuilder.setTitle(title);// 設置消息標題 androidNotifiBuilder.setBody(body);// 設置消息內容 AndroidNotification androidNotification=androidNotifiBuilder.build(); androidConfigBuilder.setNotification(androidNotification); AndroidConfig androidConfig=androidConfigBuilder.build(); //構建消息 Message message = Message.builder() .setToken(token) .setAndroidConfig(androidConfig) .build(); //發送後,返回messageID String response = FirebaseMessaging.getInstance(firebaseApp).send(message); System.out.println("單個安卓設備推送成功 : "+response); } /** * Android按主題推送(和sendTopicMes方法幾乎沒有區別) * @param appName 應用的名字 * @param topic 主題的名字 * @param title 消息題目 * @param body 消息體 * @return * @throws FirebaseMessagingException * @throws IOException */ public static void sendTopicMesToAndroid(String appName, String topic, String title, String body) throws FirebaseMessagingException, IOException { //獲取實例 FirebaseApp firebaseApp = firebaseAppMap.get(appName); //實例爲空的狀況 if (firebaseApp == null) { return; } androidNotifiBuilder.setColor("#55BEB7");// 設置消息通知顏色 androidNotifiBuilder.setIcon("https://www.shiku.co/images/favicon.png");// 設置消息圖標 androidNotifiBuilder.setTitle(title);// 設置消息標題 androidNotifiBuilder.setBody(body);// 設置消息內容 AndroidNotification androidNotification=androidNotifiBuilder.build(); androidConfigBuilder.setNotification(androidNotification); AndroidConfig androidConfig=androidConfigBuilder.build(); //構建消息 Message message = Message.builder() .setTopic(topic) .setAndroidConfig(androidConfig) .build(); String response = FirebaseMessaging.getInstance(firebaseApp).send(message); System.out.println("安卓主題推送成功: " + response); } }
##測試類服務器
import java.util.LinkedList; import java.util.List; /** *測試FCM * @author Feiqs * @version 建立時間:2019年4月23日 上午10:52:53 */ public class Test { private static final String String = null; //設備的token值 public static String token = "e1v12xfHs3g:APA91bFExfQRg1h4AZc3GqLHxW4ohe3D7Ca0xvGMJkSbY3qe9yXf4Xe10c1O4fHJ2IkbsNF6Z0lr97EV7G1ybP4GLDY5nGVa1ufLOtMAKhcXBfua1bGvubf5whjTLuFj6BQdflFz2n2w"; //渠道名字,也是APP的名字 public static String appName = "myAppName"; //主題名字 public static String topic = "China"; //通知消息題目 public static String title = "tip"; //通知消息內容 public static String body = "are you ok?"; //測試內容 public static void main(String args [] ) throws Exception { //添加tokens List<String> tokens = new LinkedList(); tokens.add(token); //設置Java代理,端口號是代理軟件開放的端口,這個很重要。 System.setProperty("proxyHost", "localhost"); System.setProperty("proxyPort", "1080"); //若是FirebaseApp沒有初始化 if(!FireBaseUtil.isInit(appName)) { String jsonPath = "path/to/serviceAccountKey.json" ; String dataUrl = "https://telecomm-773e6e.firebaseio.com/"; //初始化FirebaseApp FireBaseUtil.initSDK(jsonPath, dataUrl, appName); } FireBaseUtil.pushSingle(appName, token, title, body); //單推 FireBaseUtil.registrationTopic(appName, tokens, topic); //設置主題 FireBaseUtil.sendTopicMes(appName, topic, title, body); //按主題推送 FireBaseUtil.cancelTopic(appName, tokens, topic); //取消主題 //安卓設備推送 FireBaseUtil.pushSingleToAndroid(appName, token, title, body); FireBaseUtil.registrationTopic(appName, tokens, topic); //設置主題 FireBaseUtil.sendTopicMesToAndroid(appName, topic, title, body); } }
##總結網絡