aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle1
-rw-r--r--src/main/java/org/traccar/config/Keys.java6
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorFirebase.java86
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorTraccar.java55
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();
+ }
}
}