package com.juick.components; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutureCallback; import com.google.api.core.ApiFutures; import com.google.auth.oauth2.GoogleCredentials; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.Message; import com.juick.ExternalToken; import com.juick.User; import com.juick.service.component.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.task.TaskExecutor; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.io.IOException; import java.util.List; import java.util.stream.Collectors; public class FirebaseManager implements NotificationListener { private static Logger logger = LoggerFactory.getLogger(FirebaseManager.class); @Inject ObjectMapper jsonMapper; @Value("${fcm_database_url:}") private String fcmDatabaseUrl; @Inject private NotificationsManager notificationsManager; @Inject private TaskExecutor taskExecutor; @PostConstruct public void initialize() throws IOException { Resource serviceAccount = new ClassPathResource("serviceAccount.json"); FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount.getInputStream())) .setDatabaseUrl(fcmDatabaseUrl) .build(); FirebaseApp.initializeApp(options); } @Override public void processMessageEvent(MessageEvent messageEvent) { com.juick.Message jmsg = messageEvent.getMessage(); List users = messageEvent.getUsers(); // GCM List regids = users.stream().flatMap(u -> u.getTokens().stream()).filter(d -> d.getType().equals("gcm")) .map(ExternalToken::getToken).collect(Collectors.toList()); if (!regids.isEmpty()) { String json = null; try { json = jsonMapper.writeValueAsString(jmsg); } catch (JsonProcessingException e) { logger.warn("JSON exception", e); } logger.info(json); Message.Builder messageBuilder = Message.builder() .putData("message", json); regids.forEach(token -> { messageBuilder.setToken(token); ApiFuture response = FirebaseMessaging.getInstance().sendAsync(messageBuilder.build()); ApiFutures.addCallback(response, new ApiFutureCallback() { @Override public void onFailure(Throwable t) { logger.warn("Firebase exception", t); /* List results = result.getResults(); for (int i = 0; i < results.size(); i++) { Result currentResult = results.get(i); logger.info("RES {}: {}", i, currentResult); List errorCodes = Arrays.asList(Constants.ERROR_MISMATCH_SENDER_ID, Constants.ERROR_NOT_REGISTERED); if (errorCodes.contains(currentResult.getErrorCodeName())) { // assuming results are in order of regids // http://stackoverflow.com/a/11594531/1097384 String currentId = regids.get(i); logger.info("{} is scheduled to remove", currentId); notificationsManager.addInvalidGCMToken(currentId); } }*/ } @Override public void onSuccess(String result) { logger.info("Successfully sent message: " + result); } }, taskExecutor); }); } else { logger.info("GMS: no recipients"); } } @Override public void processSubscribeEvent(SubscribeEvent subscribeEvent) { } @Override public void processLikeEvent(LikeEvent likeEvent) { } @Override public void processPingEvent(PingEvent pingEvent) { } @Override public void processMessageReadEvent(MessageReadEvent messageReadEvent) { } @Override public void processTopEvent(TopEvent topEvent) { } }