diff options
author | Anton Tananaev <anton@traccar.org> | 2022-07-16 11:41:53 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-07-16 11:41:53 -0700 |
commit | ca4488bd093d25afa494ab30e117fdef98e20013 (patch) | |
tree | 3de6f9d345759873f4cfb19f1ba52b2796fc820c | |
parent | 159f0ef4861b64085cdd1c1d8d0234f47bc75797 (diff) | |
download | trackermap-server-ca4488bd093d25afa494ab30e117fdef98e20013.tar.gz trackermap-server-ca4488bd093d25afa494ab30e117fdef98e20013.tar.bz2 trackermap-server-ca4488bd093d25afa494ab30e117fdef98e20013.zip |
Migrate to Firebase SDK
-rw-r--r-- | build.gradle | 1 | ||||
-rw-r--r-- | src/main/java/org/traccar/config/Keys.java | 6 | ||||
-rw-r--r-- | src/main/java/org/traccar/notificators/NotificatorFirebase.java | 86 | ||||
-rw-r--r-- | src/main/java/org/traccar/notificators/NotificatorTraccar.java | 55 |
4 files changed, 100 insertions, 48 deletions
diff --git a/build.gradle b/build.gradle index 8ba907843..675d1490f 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.sun.xml.bind:jaxb-impl:3.0.2" implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" + implementation "com.google.firebase:firebase-admin:9.0.0" testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:3.+" } 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<String> NOTIFICATOR_FIREBASE_KEY = new StringConfigKey( - "notificator.firebase.key", + public static final ConfigKey<String> 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<String> 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(); + } } } |