firebase推送后台接入--海外APP推送

firebase推送接入运营后台


海外推送接入firebase,实现管理员在app后台推送相关信息,一下主要描述后台接入逻辑以及常见问题

**注意:由于国内防火墙的原因,无法直接访问firebaseApi

              1)app接入firebase需要;

              2)以下后台管理接入firebase即使不管用,需要在可以直接访问firebase的网络环境下运行;

一、实现基本流程

    1)APP端接入firebase的SDK,并在应用启动时候获取registrationToken(对应设备注册token)传入后台;

    2)APP后台将获取的token与设备id对应存储,根据需要可以为设备订阅相关主题,群推可进行主题推送;

二、管理员后台接入实现(java)

    官方文档:https://firebase.google.com/docs/admin/setup?hl=zh-cn

     1)将firebase添加到后台

dependencies {
  implementation 'com.google.firebase:firebase-admin:6.5.0'
}

  com.google.firebase
  firebase-admin
  6.5.0

    2)初始化SDK(以下为单应用初始化,后面将介绍初始化多应用)

FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");

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

FirebaseApp.initializeApp(options);

    3)设备主题订阅(主题名称由后台自定义)

// 需要订阅的设备token
List registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

// 订阅
// topic.主题名称
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopicAsync(
    registrationTokens, topic).get();
// 返回结果
System.out.println(response.getSuccessCount() + " tokens were subscribed successfully");

    4)设备取消主题订阅

// 需要取消的设备token
List registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

// 取消订阅
// the topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().unsubscribeFromTopicAsync(
    registrationTokens, topic).get();
// 返回结果
System.out.println(response.getSuccessCount() + " tokens were unsubscribed successfully");

    5)单个设备推送

// 需要推送的设备token
String registrationToken = "YOUR_REGISTRATION_TOKEN";

// 推送的消息体,data为自定义消息体
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setToken(registrationToken)
    .build();

// 发送消息
String response = FirebaseMessaging.getInstance().send(message);

System.out.println("Successfully sent message: " + response);

6)向某个主题推送消息

// 主题名.
String topic = "highScores";

// 消息体
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setTopic(topic)
    .build();

// 发送
String response = FirebaseMessaging.getInstance().send(message);
//返回值
System.out.println("Successfully sent message: " + response);

 三、多应用初始化以及推送管理

       以上为基本的单应用设备推送方案,若需要同时管理多个应用(如多个马甲包情况),需要初始化多个FirebaseApp,以下以代码实现为例:

@Component
public class FireBaseUtil {

    @Autowired
    private FirebaseConfigMapper configMapper;//查找多个应用秘钥mapp(多应用及秘钥保存于数据库)
    //保存多个初始化的FirebaseApp实例,避免多次初始化
    private Map firebaseAppMap = new ConcurrentHashMap<>();

    private final Logger logger = LoggerFactory.getLogger(FireBaseUtil.class);
    /**
     * 获取实例
     * @param channelCode 渠道名作为应用名,获取初始化配置
     * @return
     */
    private FirebaseMessaging getMessageInstance(String channelCode){
        try {
            FirebaseApp firebaseApp = firebaseAppMap.get(channelCode);
            if (firebaseApp == null){
                FirebaseConfigDO firebaseConfigDO = configMapper.findByChannelCode(channelCode);
                if (firebaseConfigDO == null){
                    return null;
                }
                FirebaseOptions options = new FirebaseOptions.Builder()
                        .setCredentials(GoogleCredentials.fromStream(new ByteArrayInputStream(firebaseConfigDO.getAccountJson().getBytes())))
                        .setDatabaseUrl(firebaseConfigDO.getDatabaseUrl())
                        .build();
                firebaseApp = FirebaseApp.initializeApp(options,channelCode);
                firebaseAppMap.put(channelCode,firebaseApp);
            }
            return FirebaseMessaging.getInstance(firebaseApp);
        }catch (Exception e){
            throw new ServiceException(e);
        }
    }

    /**
     * 主题订阅
     * @param channelCode 渠道名,用作实例化的应用名
     * @param token
     * @param topic
     */
    @Async
    public void subTopic(String channelCode, String token, FirebaseTopicEnum topic){
        List tokens = new ArrayList<>();
        tokens.add(token);
        subTopic(channelCode,tokens,topic);
    }

    public void subTopic(String channelCode, List tokends, FirebaseTopicEnum topic){
        FirebaseMessaging instance = getMessageInstance(channelCode);
        if (instance == null)
            return;
        try {
            instance.subscribeToTopic(tokends, topic.getTopic());
        } catch (FirebaseMessagingException e) {
            e.printStackTrace();
        }
    }
    

    /**
     * 取消订阅
     * @param channelCode 渠道名,用作实例化的应用名
     * @param token
     * @param topic
     */
    public void unSubTopic(String channelCode, String token, FirebaseTopicEnum topic){
        List tokens = new ArrayList<>();
        tokens.add(token);
        unSubTopic(channelCode,tokens,topic);
    }
    @Async
    public void unSubTopic(String channelCode, List tokends, FirebaseTopicEnum topic){
        FirebaseMessaging instance = getMessageInstance(channelCode);
        if (instance == null)
            return;
        try {
            instance.unsubscribeFromTopic(tokends,topic.getTopic());
        } catch (FirebaseMessagingException e) {
            e.printStackTrace();
        }
    }
    

    /**
     * 单推
     * @param channelCode 渠道号
     * @param token 注册token
     * @param pushData 推送数据
     */
    public void pushSingle(String channelCode, String token, PushDataBO pushData){
        FirebaseMessaging messageInstance = getMessageInstance(channelCode);
        if (messageInstance == null)
            return;
        try {
            messageInstance.send(messageBuild(pushData, token, null));
            logger.info("设备推送成功 : "+token);
        } catch (FirebaseMessagingException e) {
            e.printStackTrace();
        }
    }
    

    /**
     * 主题推送
     * @param channelCode 渠道
     * @param topicEnum 主题
     * @param pushData 消息内容
     */
    @Async
    public void pushTopic(String channelCode, FirebaseTopicEnum topicEnum, PushDataBO pushData){
        FirebaseMessaging messageInstance = getMessageInstance(channelCode);
        if (messageInstance == null)
            return;
        try {
            messageInstance.send(messageBuild(pushData, null, topicEnum));
            logger.info("主题推送成功 :" + topicEnum.getName());
        } catch (FirebaseMessagingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建消息
     * @param pushData 消息内容
     * @param token 单设备推送携带,否则未null
     * @param topicEnum 主题推送携带,否则未null,自定义的主题枚举
     * @return
     */
    private Message messageBuild(PushDataBO pushData,String token,FirebaseTopicEnum topicEnum){
        Message.Builder builder = Message.builder()
                .setNotification(new Notification(pushData.getTitle(), pushData.getBody()))
                .putData("pushType", pushData.getPushType().getType())
                .putData("openData", pushData.getOpenData()==null?"default":pushData.getOpenData());
        if (token != null){//单设备推送
            builder.setToken(token);
        }else {//订阅主题推送
            builder.setTopic(topicEnum.getTopic());
        }
        return builder.build();
    }
}

以上代码应用于个人项目,若有疑问,多多指教!!! 

 

你可能感兴趣的:(Java)