Notificações por push do servidor SpringBoot

Prefácio


Eu te saúdo. Recentemente, enfrentei o desafio de configurar notificações push no site. Foi a primeira vez que me deparei com isso, e este artigo me ajudou muito. Ele já contém uma descrição do lado do servidor, mas, no processo de estudo deste tópico, encontrei uma maneira mais conveniente de implementar os meios da própria biblioteca Firebase. Na verdade, eu gostaria de falar sobre ele, porque Não consegui encontrar uma explicação clara na Internet.

Este artigo também pode ser útil para programadores em Node.js, Python e Go, pois a biblioteca também está disponível nesses idiomas.

Direto ao ponto


Neste artigo, falarei apenas do lado do servidor.
(você pode configurar a parte do cliente usando o mesmo artigo )
Então:

  • Primeiro você precisa ir ao site , se registrar e criar um projeto.
  • Em seguida, no canto superior esquerdo, clique na engrenagem e selecione "Configurações do projeto".
  • Vá para a guia "Contas de serviço", selecione o idioma de seu interesse, clique em "criar uma chave privada" e faça o download do arquivo gerado
Este arquivo JSON contém a configuração necessária para a biblioteca Firebase.
Agora vamos cuidar do servidor

Por conveniência, declare o caminho para o arquivo baixado em application.properties

fcm.service-account-file = /path/to/file.json 

Adicione as dependências necessárias no pom.xml

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

Crie um bean que retorne nosso JSON:

 @ConfigurationProperties(prefix = "fcm") @Component public class FcmSettings { private String serviceAccountFile; public String getServiceAccountFile() { return this.serviceAccountFile; } public void setServiceAccountFile(String serviceAccountFile) { this.serviceAccountFile = serviceAccountFile; } } 


Objeto de configuração

 @Getter @Setter public class PushNotifyConf { private String title; private String body; private String icon; private String click_action; private String ttlInSeconds; public PushNotifyConf() { } public PushNotifyConf(String title, String body, String icon, String click_action, String ttlInSeconds) { this.title = title; this.body = body; this.icon = icon; this.click_action = click_action; this.ttlInSeconds = ttlInSeconds; } } 

Campos:
  • title - Sumário
  • corpo - texto de notificação
  • ícone - link para a imagem
  • click_action - o link para onde o usuário irá quando clicar na notificação (com um nome, exemplo no serviço)
    Você pode adicionar vários deles, mas nem todos os navegadores exibirão tudo (abaixo está um exemplo do Chroma)
  • ttlInSeconds - tempo de validade da notificação


E o serviço, que será toda a lógica do envio de notificações:

 @Service public class FcmClient { public FcmClient(FcmSettings settings) { Path p = Paths.get(settings.getServiceAccountFile()); try (InputStream serviceAccount = Files.newInputStream(p)) { FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount)) .build(); FirebaseApp.initializeApp(options); } catch (IOException e) { Logger.getLogger(FcmClient.class.getName()) .log(Level.SEVERE, null, e); } } public String sendByTopic(PushNotifyConf conf, String topic) throws InterruptedException, ExecutionException { Message message = Message.builder().setTopic(topic) .setWebpushConfig(WebpushConfig.builder() .putHeader("ttl", conf.getTtlInSeconds()) .setNotification(createBuilder(conf).build()) .build()) .build(); String response = FirebaseMessaging.getInstance() .sendAsync(message) .get(); return response; } public String sendPersonal(PushNotifyConf conf, String clientToken) throws ExecutionException, InterruptedException { Message message = Message.builder().setToken(clientToken) .setWebpushConfig(WebpushConfig.builder() .putHeader("ttl", conf.getTtlInSeconds()) .setNotification(createBuilder(conf).build()) .build()) .build(); String response = FirebaseMessaging.getInstance() .sendAsync(message) .get(); return response; } public void subscribeUsers(String topic, List<String> clientTokens) throws FirebaseMessagingException { for (String token : clientTokens) { TopicManagementResponse response = FirebaseMessaging.getInstance() .subscribeToTopic(Collections.singletonList(token), topic); } } private WebpushNotification.Builder createBuilder(PushNotifyConf conf){ WebpushNotification.Builder builder = WebpushNotification.builder(); builder.addAction(new WebpushNotification .Action(conf.getClick_action(), "")) .setImage(conf.getIcon()) .setTitle(conf.getTitle()) .setBody(conf.getBody()); return builder; } } 

Eu: - Firebase, por que existem tantas compilações?
Firebase: - Porque
  1. O construtor é usado para inicializar o FirebaseApp usando nosso arquivo JSON.
  2. O método sendByTopic () envia notificações para usuários inscritos em um determinado tópico.
  3. O método subscribeUsers () assina um tópico (tópico) de usuários (clientTokens).
    pode ser executado de forma assíncrona, para isso .subscribeToTopicAsync () é usado

  4. O método sendPersonal () implementa o envio de uma notificação pessoal para o usuário (clientToken)
  5. O método createBuilder () cria uma mensagem

Resultado

imagem

Outro navegador

imagem
Não há ícones porque o Ubuntu :)

Resumir



Em essência, a biblioteca Firebase coleta JSON para nós assim:

 {from: "Server key"​ notification: {​​ title: " Habr" actions: (1) [​​​ 0: Object { action: "https://habr.com/ru/top/", title: "" } ]​​ length: 1​​ body: "- "​​ image: "https://habrastorage.org/webt/7i/k5/77/7ik577fzskgywduy_2mfauq1gxs.png"​​ } ​priority: "normal"} 

E no lado do cliente, você já está analisando como quiser.

Obrigado pela atenção!

Links úteis:


firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/messaging/WebpushNotification

habr.com/en/post/321924/#otpravka-uvedomleniy-s-servera

firebase.google.com/docs/web/setup

Source: https://habr.com/ru/post/pt442202/


All Articles