136 lines
5.2 KiB
Java
136 lines
5.2 KiB
Java
package im.rosetta.service.dispatch;
|
||
|
||
import java.io.FileInputStream;
|
||
import java.io.IOException;
|
||
import java.util.List;
|
||
import java.util.concurrent.ExecutorService;
|
||
import java.util.concurrent.Executors;
|
||
|
||
import com.google.auth.oauth2.GoogleCredentials;
|
||
import com.google.firebase.FirebaseApp;
|
||
import com.google.firebase.FirebaseOptions;
|
||
import com.google.firebase.messaging.FirebaseMessaging;
|
||
import com.google.firebase.messaging.Message;
|
||
import com.google.firebase.messaging.Notification;
|
||
|
||
import im.rosetta.database.repository.UserRepository;
|
||
import im.rosetta.service.services.UserService;
|
||
|
||
/**
|
||
* Класс для отправки push-уведомлений пользователям через Firebase Cloud Messaging (FCM).
|
||
*/
|
||
public class FirebaseDispatcher {
|
||
|
||
private UserRepository userRepository = new UserRepository();
|
||
private UserService userService = new UserService(userRepository);
|
||
private final ExecutorService executor = Executors.newFixedThreadPool(10);
|
||
|
||
public FirebaseDispatcher() {
|
||
initializeFirebase();
|
||
}
|
||
|
||
/**
|
||
* Инициализация Firebase Admin SDK
|
||
*/
|
||
private void initializeFirebase() {
|
||
if (FirebaseApp.getApps().isEmpty()) {
|
||
try {
|
||
String firebaseCredentialsPath = System.getenv("FIREBASE_CREDENTIALS_PATH");
|
||
if (firebaseCredentialsPath == null || firebaseCredentialsPath.isEmpty()) {
|
||
throw new IllegalStateException("FIREBASE_CREDENTIALS_PATH environment variable is not set");
|
||
}
|
||
|
||
FileInputStream serviceAccount = new FileInputStream(firebaseCredentialsPath);
|
||
FirebaseOptions options = FirebaseOptions.builder()
|
||
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
|
||
.build();
|
||
FirebaseApp.initializeApp(options);
|
||
} catch (IOException e) {
|
||
throw new RuntimeException("Failed to initialize Firebase", e);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Отправляет push-уведомление пользователю с данным публичным ключом (асинхронно)
|
||
* @param publicKey публичный ключ пользователя
|
||
* @param title заголовок уведомления
|
||
* @param messageText текст уведомления
|
||
*/
|
||
public void sendPushNotification(String publicKey, String title, String messageText) {
|
||
executor.submit(() -> {
|
||
try {
|
||
List<String> tokens = userService.getNotificationsTokens(publicKey);
|
||
if (tokens == null || tokens.isEmpty()) {
|
||
return;
|
||
}
|
||
|
||
for (String token : tokens) {
|
||
try {
|
||
Message message = Message.builder()
|
||
.setNotification(Notification.builder()
|
||
.setTitle(title)
|
||
.setBody(messageText)
|
||
.build())
|
||
.setToken(token)
|
||
.build();
|
||
|
||
FirebaseMessaging.getInstance().send(message);
|
||
} catch (Exception e) {
|
||
// Логирование ошибки
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
// Логирование ошибки
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Отправляет push-уведомление нескольким пользователям (асинхронно)
|
||
* @param publicKeys список публичных ключей пользователей
|
||
* @param title заголовок уведомления
|
||
* @param messageText текст уведомления
|
||
*/
|
||
public void sendPushNotification(List<String> publicKeys, String title, String messageText) {
|
||
executor.submit(() -> {
|
||
for (String publicKey : publicKeys) {
|
||
sendPushNotificationSync(publicKey, title, messageText);
|
||
}
|
||
});
|
||
}
|
||
|
||
private void sendPushNotificationSync(String publicKey, String title, String messageText) {
|
||
try {
|
||
List<String> tokens = userService.getNotificationsTokens(publicKey);
|
||
if (tokens == null || tokens.isEmpty()) {
|
||
return;
|
||
}
|
||
|
||
for (String token : tokens) {
|
||
try {
|
||
Message message = Message.builder()
|
||
.setNotification(Notification.builder()
|
||
.setTitle(title)
|
||
.setBody(messageText)
|
||
.build())
|
||
.setToken(token)
|
||
.build();
|
||
|
||
FirebaseMessaging.getInstance().send(message);
|
||
} catch (Exception e) {
|
||
// Логирование ошибки
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
// Логирование ошибки
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Завершить работу executor при остановке приложения
|
||
*/
|
||
public void shutdown() {
|
||
executor.shutdown();
|
||
}
|
||
} |