From ca4488bd093d25afa494ab30e117fdef98e20013 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 11:41:53 -0700 Subject: Migrate to Firebase SDK --- src/main/java/org/traccar/config/Keys.java | 6 +- .../traccar/notificators/NotificatorFirebase.java | 86 +++++++++++----------- .../traccar/notificators/NotificatorTraccar.java | 55 +++++++++++++- 3 files changed, 99 insertions(+), 48 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 5f31fe99c..1217ab94c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -978,10 +978,10 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Firebase server API key for push notifications. + * Firebase service account JSON. */ - public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new StringConfigKey( - "notificator.firebase.key", + public static final ConfigKey NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT = new StringConfigKey( + "notificator.firebase.serviceAccount", List.of(KeyType.CONFIG)); /** diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 17a6735ee..ecf3fbb70 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -16,73 +16,77 @@ */ package org.traccar.notificators; -import com.fasterxml.jackson.annotation.JsonProperty; +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.AndroidNotification; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.MulticastMessage; +import com.google.firebase.messaging.Notification; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; +import javax.inject.Singleton; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +@Singleton public class NotificatorFirebase implements Notificator { private final NotificationFormatter notificationFormatter; - private final Client client; - private final String url; - private final String key; + @Inject + public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter) throws IOException { - public static class Notification { - @JsonProperty("title") - private String title; - @JsonProperty("body") - private String body; - @JsonProperty("sound") - private String sound; - } + this.notificationFormatter = notificationFormatter; - public static class Message { - @JsonProperty("registration_ids") - private String[] tokens; - @JsonProperty("notification") - private Notification notification; - } + InputStream serviceAccount = new ByteArrayInputStream( + config.getString(Keys.NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT).getBytes()); - @Inject - public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter, Client client) { - this( - notificationFormatter, client, "https://fcm.googleapis.com/fcm/send", - config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); - } + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(serviceAccount)) + .build(); - protected NotificatorFirebase( - NotificationFormatter notificationFormatter, Client client, String url, String key) { - this.notificationFormatter = notificationFormatter; - this.client = client; - this.url = url; - this.key = key; + FirebaseApp.initializeApp(options); } @Override - public void send(User user, Event event, Position position) { + public void send(User user, Event event, Position position) throws MessageException { if (user.hasAttribute("notificationTokens")) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); - Notification notification = new Notification(); - notification.title = shortMessage.getSubject(); - notification.body = shortMessage.getBody(); - notification.sound = "default"; + List registrationTokens = Arrays.asList(user.getString("notificationTokens").split("[, ]")); - Message message = new Message(); - message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; + MulticastMessage message = MulticastMessage.builder() + .setNotification(Notification.builder() + .setTitle(shortMessage.getSubject()) + .setBody(shortMessage.getBody()) + .build()) + .setAndroidConfig(AndroidConfig.builder() + .setNotification(AndroidNotification.builder() + .setSound("default") + .build()) + .build()) + .addAllTokens(registrationTokens) + .build(); - client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + try { + FirebaseMessaging.getInstance().sendMulticast(message); + } catch (FirebaseMessagingException e) { + throw new MessageException(e); + } } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 8f1260e96..cb8647335 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -15,20 +15,67 @@ */ package org.traccar.notificators; +import com.fasterxml.jackson.annotation.JsonProperty; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; -public class NotificatorTraccar extends NotificatorFirebase { +public class NotificatorTraccar implements Notificator { + + private final NotificationFormatter notificationFormatter; + private final Client client; + + private final String url; + private final String key; + + public static class Notification { + @JsonProperty("title") + private String title; + @JsonProperty("body") + private String body; + @JsonProperty("sound") + private String sound; + } + + public static class Message { + @JsonProperty("registration_ids") + private String[] tokens; + @JsonProperty("notification") + private Notification notification; + } @Inject public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { - super( - notificationFormatter, client, "https://www.traccar.org/push/", - config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); + this.notificationFormatter = notificationFormatter; + this.client = client; + this.url = "http://localhost:3001/push/"; + this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); + } + + @Override + public void send(User user, Event event, Position position) { + if (user.hasAttribute("notificationTokens")) { + + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); + + Notification notification = new Notification(); + notification.title = shortMessage.getSubject(); + notification.body = shortMessage.getBody(); + notification.sound = "default"; + + Message message = new Message(); + message.tokens = user.getString("notificationTokens").split("[, ]"); + message.notification = notification; + + client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + } } } -- cgit v1.2.3