Envoi de messages Firebase cloud avec une application Spring boot

Firebase est une suite de produits fantastique, mais la documentation n’est pas toujours claire – même si elle est très riche, ce n’est pas évident de voir comment l’appliquer à son projet. Les langages et technos utilisées varient et j’ai trouvé que ça prend beaucoup de temps de passer de la documentation à l’implémentation dans son projet.

Ici, je vais documenter comment j’ai réussi à configurer mon backend Spring boot de manière à envoyer des messages avec Firebase Cloud Messaging. Pour le moment, je ne montrerai pas comment les recevoir sur une appli mobile, ni comment mettre en place le projet Firebase; j’estime qu’il y a déjà pas mal de documentation sur ces sujets en ligne (voir https://firebase.google.com/docs/cloud-messaging/android/receive?authuser=0 pour la msie en place d’une appli Android cliente).

Prérequis

Mise en place d’un projet Spring boot pour envoyer des messages avec Firebase Cloud messaging

  1. Allez à l’URL https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk et sélectionnez votre projet. Sous l’onglet « Service accounts », cliquer sur le bouton “Generate new private key”. Sauvegardez ce fichier dans votre projet, et renommez-le ainsi “firebase-privateKey.json”. (Faites attention: ce fichier est confidentiel. Ne le committez jamais sur un repo public!).
  1. Dans votre projet, configurez votre build.gradle comme suit. J’y ai ajouté les dépendances Spring boot starter web, et Firebase admin. (Si vous utilisez Maven, ajoutez ces dépendances comme les autres).

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.1.1.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
}

group 'fr.nevechris'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.13

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.google.firebase:firebase-admin:6.12.2'
}
  1. Créez une classe Application.java class comme suit:
package fr.nevechris.firebasespringpoc;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        initializeFirebaseAdmin();
    }

    private static void initializeFirebaseAdmin() {
        try {
            FileInputStream serviceAccount =
                    new FileInputStream("firebase-privateKey.json"); // Chemin de la clé privée sauvegardée à l'étape précédente

            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                    .setDatabaseUrl("DATABASE URL COMME ELLE APPARAIT DANS LA CAPTURE")
                    .build();

            FirebaseApp.initializeApp(options);
        } catch (FileNotFoundException e) {
            System.out.println("Clée privée introuvable! Tout ce qui est Firebase Admin ne fonctionnera pas.");
        } catch (IOException e) {
            System.out.println("Erreur lors de l'initialisation de Firebase Admin! Tout ce qui est Firebase Admin ne fonctionnera pas.");
        }
    }
}

Notes:

  • L’URL de la base de données que vous devez spécifier est celle indiquée dans le code Java sur la console Firebase. Voir capture d’écran à l’étape précédente.
  • La clé privée est celle que vous avez enregistrée à l’étape précédente.
  1. Créez un controller pour tester la fonctionnalité.
package fr.nevechris.firebasespringpoc;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MessageController {

    private MessageService service;

    public MessageController(MessageService service) {
        this.service = service;
    }

    @RequestMapping("/send-message")
    public void sendSampleMessage() {
        service.sendFirebaseMessage();
    }
}
  1. Créez un service pour l’envoi du message.
package fr.nevechris.firebasespringpoc;

import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.FirebaseMessagingException;
import com.google.firebase.messaging.Message;
import org.springframework.stereotype.Service;

@Service
public class MessageService {

    public void sendFirebaseMessage() {
        // Ce token est celui du device client auquel vous envoyez le message. Vous l'obtiendrez quand ce device s'enregistre auprès de Firebase.
        // Pour une appli Android, vous la trouverez ainsi:
        // FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
        //      @Override
        //      public void onComplete(@NonNull Task<InstanceIdResult> task) {
        //          if (!task.isSuccessful()) {
        //              Log.w(TAG, "getInstanceId failed", task.getException());
        //              return;
        //          }
        //          String token = task.getResult().getToken();
        //      }
        //  });
        String registrationToken = "votre-token";

        // Données de votre message. Paires clé/valeur accessibles depuis une appli Android comme suit:
        // instanceOfRemoteData.getData().get("firstName")
        Message message = Message.builder()
                .putData("firstName", "James")
                .putData("lastName", "Bond")
                .setToken(registrationToken)
                .build();

        // Envoi du message avec registration token et données.
        String response = null;
        try {
            response = FirebaseMessaging.getInstance().send(message);
        } catch (FirebaseMessagingException e) {
            System.out.println("Error sending Firebase message: " + e.getMessage());
        }
    }
}

C’est tout! Démarrez votre appli Spring boot; lorsque vous enverrez une requête à http://localhost:8080/send-message , si votre registration token est associé à un terminal, celui-ci recevra un message.

J’espère que ça vous a aidé; le code source est dispo sur mon GitHub. https://github.com/ChrisLeNeve/fcm-springboot-poc

Publié dans : Code