Như bạn có thể nhận thấy, gần đây tôi đã làm quen với chủ đề thông báo đẩy Tin nhắn qua đám mây của Firebase Lần này tôi muốn chia sẻ với bạn ứng dụng phía máy chủ thông báo đẩy của tôi. Ứng dụng được tạo bằng khung Spring Boot Ví dụ được cung cấp bao gồm hầu hết các trường hợp sử dụng gửi thông báo phổ biến, chẳng hạn như. gửi thông báo đẩy đến một chủ đề, trực tiếp đến thiết bị của người dùng hoặc gửi tin nhắn có tải trọng dữ liệu bổ sung Bài đăng này không phải là hướng dẫn từng bước. Tôi sẽ tập trung vào những phần quan trọng nhất. Một ví dụ hoạt động đầy đủ có sẵn trên GitHub Nếu bạn chưa có ứng dụng phía máy khách để nhận thông báo đẩy, bạn nên xem xét việc sử dụng ứng dụng Ionic mà tôi đã mô tả trước đó. Chúc vui vẻ Đi nàoHãy bắt đầu với việc tích hợp Firebase Trước hết, bạn phải tạo khóa quản trị SDK Firebase của riêng mình. Về cơ bản, đó là một tệp JSON chứa thông tin đăng nhập dự án Firebase của bạn. Bạn sẽ cần nó để ủy quyền phía máy chủ (thông tin thêm) Đăng nhập vào bảng điều khiển Firebase của bạn. Chuyển đến Cài đặt dự án -> Tài khoản dịch vụ rồi nhấp vào nút Tạo khóa riêng tư mới Tạo và lưu tệp. Chúng tôi sẽ sử dụng nó trong các bước tiếp theo Ứng dụng khởi động mùa xuânĐặt tệp JSON SDK quản trị Firebase đã tạo bên trong các tệp dự án Spring Boot của bạn (nếu không có, bạn có thể tạo tệp đó tại đây) Trong trường hợp của tôi, tôi đã tạo thư mục google bên trong src/main/resources và sau đó sao chép tệp được tạo vào đó (thông báo đẩy- . json) . Sau đó, trong ứng dụng của tôi. thuộc tính, tôi đã thêm một cặp khóa/giá trị mới chứa đường dẫn tệp. app.firebase-configuration-file=google/push-notifications-example-firebase-adminsdk.json
Bây giờ, chúng tôi sẽ cần các phụ thuộc Firebase, vì vậy hãy thêm một số. Tôi đã sử dụng Maven làm người quản lý phụ thuộc trong pom của tôi. phụ thuộc xml tôi đặt một phụ thuộc bổ sung <dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>6.8.1</version>
</dependency>
Bây giờ chúng ta phải khởi tạo ứng dụng Firebase của mình. Đây là thời gian để sử dụng ứng dụng của chúng tôi. tệp cấu hình firebase. Tôi đã sử dụng chú thích @Value để đưa giá trị đường dẫn vào trường Chuỗi ...
@Service
public class FCMInitializer {
@Value("${app.firebase-configuration-file}")
private String firebaseConfigPath;
Logger logger = LoggerFactory.getLogger(FCMInitializer.class);
@PostConstruct
public void initialize() {
try {
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())).build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
logger.info("Firebase application has been initialized");
}
} catch (IOException e) {
logger.error(e.getMessage());
}
}
}
Trình khởi tạo FCMI. java Phương thức khởi tạo () đang được gọi khi khởi động ứng dụng nhờ chú thích @PostConstruct Gửi thông báo đẩyBước tiếp theo là chuẩn bị lớp dịch vụ thông báo đẩy của chúng tôi. Nhưng trước hết, tôi tách các trường hợp sử dụng sau. - gửi thông báo đẩy tới chủ đề bằng dữ liệu mẫu (được xác định trong ứng dụng. của cải)
- gửi thông báo đẩy mẫu theo lịch trình đến chủ đề (mỗi phút)
- gửi thông báo đẩy với tải trọng dữ liệu bổ sung (đối tượng dữ liệu khóa/giá trị do người dùng xác định, xem tài liệu để biết thêm thông tin)
- gửi thông báo đẩy mà không cần tải dữ liệu bổ sung
- gửi thông báo đẩy tới một người dùng cụ thể
Gửi thông báo đẩy mà không có ví dụ tải trọng dữ liệu từ lớp FCMService @Service
public class FCMService {
...
public void sendMessageWithoutData(PushNotificationRequest request)
throws InterruptedException, ExecutionException {
Message message = getPreconfiguredMessageWithoutData(request);
String response = sendAndGetResponse(message);
logger.info("Sent message without data. Topic: " + request.getTopic() + ", " + response);
}
...
private String sendAndGetResponse(Message message) throws InterruptedException, ExecutionException {
return FirebaseMessaging.getInstance().sendAsync(message).get();
}
private AndroidConfig getAndroidConfig(String topic) {
return AndroidConfig.builder()
.setTtl(Duration.ofMinutes(2).toMillis()).setCollapseKey(topic)
.setPriority(AndroidConfig.Priority.HIGH)
.setNotification(AndroidNotification.builder().setSound(NotificationParameter.SOUND.getValue())
.setColor(NotificationParameter.COLOR.getValue()).setTag(topic).build()).build();
}
private ApnsConfig getApnsConfig(String topic) {
return ApnsConfig.builder()
.setAps(Aps.builder().setCategory(topic).setThreadId(topic).build()).build();
}
private Message getPreconfiguredMessageWithoutData(PushNotificationRequest request) {
return getPreconfiguredMessageBuilder(request).setTopic(request.getTopic())
.build();
}
...
private Message.Builder getPreconfiguredMessageBuilder(PushNotificationRequest request) {
AndroidConfig androidConfig = getAndroidConfig(request.getTopic());
ApnsConfig apnsConfig = getApnsConfig(request.getTopic());
return Message.builder()
.setApnsConfig(apnsConfig).setAndroidConfig(androidConfig).setNotification(
new Notification(request.getTitle(), request.getMessage()));
}
}
Nếu bạn thực sự muốn kiểm tra nó, bạn có thể thử chạy ứng dụng ngay bây giờ và gọi các phương thức thích hợp Trong trường hợp của tôi, để rõ ràng, tôi đã thêm một lớp khác – PushNotificationService sẽ được PushNotificationController sử dụng trực tiếp trong các bước tiếp theo Hãy xem PushNotificationService ...
@Service
public class PushNotificationService {
@Value("#{${app.notifications.defaults}}")
private Map<String, String> defaults;
private Logger logger = LoggerFactory.getLogger(PushNotificationService.class);
private FCMService fcmService;
public PushNotificationService(FCMService fcmService) {
this.fcmService = fcmService;
}
@Scheduled(initialDelay = 60000, fixedDelay = 60000)
public void sendSamplePushNotification() {
try {
fcmService.sendMessageWithoutData(getSamplePushNotificationRequest());
} catch (InterruptedException | ExecutionException e) {
logger.error(e.getMessage());
}
}
public void sendPushNotification(PushNotificationRequest request) {
try {
fcmService.sendMessage(getSamplePayloadData(), request);
} catch (InterruptedException | ExecutionException e) {
logger.error(e.getMessage());
}
}
public void sendPushNotificationWithoutData(PushNotificationRequest request) {
try {
fcmService.sendMessageWithoutData(request);
} catch (InterruptedException | ExecutionException e) {
logger.error(e.getMessage());
}
}
public void sendPushNotificationToToken(PushNotificationRequest request) {
try {
fcmService.sendMessageToToken(request);
} catch (InterruptedException | ExecutionException e) {
logger.error(e.getMessage());
}
}
private Map<String, String> getSamplePayloadData() {
Map<String, String> pushData = new HashMap<>();
pushData.put("messageId", defaults.get("payloadMessageId"));
pushData.put("text", defaults.get("payloadData") + " " + LocalDateTime.now());
return pushData;
}
private PushNotificationRequest getSamplePushNotificationRequest() {
PushNotificationRequest request = new PushNotificationRequest(defaults.get("title"),
defaults.get("message"),
defaults.get("topic"));
return request;
}
}
Dịch vụ thông báo đẩy Như bạn thấy, chúng ta lại có chú thích @Value ở đây. Tại sao? . Vì vậy, thay vì đưa một giá trị duy nhất từ các thuộc tính vào một biến Chuỗi cụ thể, tôi quyết định sử dụng loại Bản đồ để đơn giản hóa. Nó vẫn sử dụng cùng một chú thích @Value Một lần nữa, chúng tôi lưu trữ các giá trị mặc định trong ứng dụng. của cải. Vì vậy, ứng dụng. thông báo. khóa mặc định trông như thế này app.notifications.defaults={topic: 'common', title: 'Common topic - Hello', message: 'Sending test message \uD83D\uDE42', token: 'ss22t03wz208eg:APA2idkkow223FE_0v5yHxqCLTyxAQafj6nWaqi4QzwZTW004q1PUux63UsFN', payloadMessageId: '123', payloadData: 'Hello. This is payload content.'}
ứng dụng. của cải Hơn nữa, bạn có thể thấy chúng tôi đang sử dụng FCMService trực tiếp, chuyển các đối tượng yêu cầu thông báo tới nó Để lên lịch, tôi đã sử dụng chú thích @Scheduled với độ trễ ban đầu là 1 phút. (tham số initDelay) và 1 phút. khoảng thời gian gửi (tham số fixedDelay). Hãy nhớ chú thích lớp Ứng dụng của bạn với @EnableScheduling điểm cuốiHãy tương tác với các dịch vụ của chúng tôi và xây dựng bộ điều khiển Đối với mục đích trình bày, tôi đã hiển thị các phương thức dịch vụ của mình dưới dạng điểm cuối API REST để gửi tin nhắn trực tiếp, tùy chỉnh (đến chủ đề hoặc người đăng ký cụ thể) có/không có tải trọng dữ liệu hoặc kích hoạt gửi thông báo mặc định ...
@RestController
public class PushNotificationController {
private PushNotificationService pushNotificationService;
public PushNotificationController(PushNotificationService pushNotificationService) {
this.pushNotificationService = pushNotificationService;
}
@PostMapping("/notification/topic")
public ResponseEntity sendNotification(@RequestBody PushNotificationRequest request) {
pushNotificationService.sendPushNotificationWithoutData(request);
return new ResponseEntity<>(new PushNotificationResponse(HttpStatus.OK.value(), "Notification has been sent."), HttpStatus.OK);
}
...
@GetMapping("/notification")
public ResponseEntity sendSampleNotification() {
pushNotificationService.sendSamplePushNotification();
return new ResponseEntity<>(new PushNotificationResponse(HttpStatus.OK.value(), "Notification has been sent."), HttpStatus.OK);
}
}
PushNotificationController. đoạn java Kiểm tra các điểm cuối REST bằng cURLHãy kiểm tra các điểm cuối của chúng tôi. Tôi đã sử dụng cURL cho tác vụ này nhưng bạn có thể sử dụng các công cụ yêu cầu HTTP yêu thích của mình hoặc viết một ứng dụng khách nhỏ cho việc này - GET /notification – Kích hoạt thông báo mẫu với các giá trị mặc định đang gửi
curl -H "Content-Type: application/json" -X GET http://localhost:8080/notification
- POST /notification/topic – Gửi tin nhắn đến một chủ đề cụ thể
________số 8 - POST /notification/token – Gửi tin nhắn đến một thiết bị cụ thể (có token)
curl -d '{"title":"Hey you!", "message":"Watch out!", "token":"cct00ebz8eg:APA91bFcTkFE_0Qafj6nWv5yHxqCLTyxAaqi4QzwsFNLP5M9G78X8Z5UMZTW004q1PUux63Ut-1WMGVToMNTdB3ZfO8lCZlc4lGpxm7LBdWfkhaUxdbpQ5xIO5cAb-w9H2dBLNHT7i-U", "topic": ""}' -H "Content-Type: application/json" -X POST http://localhost:8080/notification/token
- POST /notification/data – Gửi tin nhắn đến một chủ đề cụ thể với dữ liệu tải trọng bổ sung.
Xin lưu ý . trong trường hợp này tôi lấy mặc định từ ứng dụng. thuộc tính như tải trọng mẫu. Trong ứng dụng của mình, có lẽ bạn nên sử dụng dữ liệu API của bên thứ ba hoặc dữ liệu liên tục từ cơ sở dữ liệu của mình.
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>6.8.1</version>
</dependency> 0 Nếu thành công, bạn sẽ nhận được phản hồi JSON sau với mã 200 <dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>6.8.1</version>
</dependency> 1Kết quảChà… Nếu được cấu hình đúng thì nó sẽ hoạt động. Tôi đã sử dụng ứng dụng Ionic và điện thoại Android với tư cách khách hàng Hãy xem ảnh chụp màn hình này với các thông báo đã nhận Trong trường hợp này, ứng dụng phía máy khách không xử lý dữ liệu tải trọng bổ sung Bạn có tò mò về màu vàng của thông báo không? . Xem tài liệu tham khảo để biết thêm mô tả trường bổ sung. Tóm lượcTrong bài đăng này, tôi đã đề cập đến việc tích hợp Firebase Cloud Messaging cơ bản với ứng dụng Spring Boot. Nếu bạn đang tìm cách triển khai thông báo đẩy phía máy chủ, tôi nghĩ đây là cách nên làm Như tôi đã đề cập trước đây, ví dụ hoạt động đầy đủ có sẵn trên GitHub. Nếu bạn đang tìm kiếm một ứng dụng di động phía máy khách cơ bản, vui lòng xem bài đăng về ứng dụng thông báo đẩy Ionic trước đây của tôi Xin lưu ý rằng ví dụ được cung cấp đã được thử nghiệm với một ứng dụng Android. Mặc dù tôi đã cung cấp một số cấu hình Dịch vụ thông báo đẩy (APNS) cơ bản của Apple nhưng bạn phải xử lý các sự cố tiềm ẩn khi phát triển ứng dụng iOS. Nếu bạn quản lý để làm điều đó xin vui lòng cho tôi biết |