Nhận tin nhắn trong các ứng dụng trên nền tảng Apple

Chọn nền tảng: iOS+ Android Web Flutter Unity C++


Sau khi được cài đặt trên một thiết bị, ứng dụng khách có thể nhận tin nhắn thông qua giao diện FCM APNs. Bạn có thể bắt đầu gửi thông báo ngay cho các phân khúc người dùng bằng Trình soạn thông báo trong bảng điều khiển Firebase hoặc tin nhắn được xây dựng trên máy chủ ứng dụng của bạn.

Xử lý thông báo cảnh báo

FCM gửi tất cả tin nhắn nhắm đến ứng dụng Apple thông qua APNs. Để tìm hiểu thêm về cách nhận thông báo APNs bằng UNUserNotificationCenter, hãy xem tài liệu của Apple về Xử lý thông báo và các thao tác liên quan đến thông báo.

Bạn phải đặt đại diện UNUserNotificationCenter và triển khai các phương thức đại diện thích hợp để nhận thông báo hiển thị từ FCM.

Swift

// Receive displayed notifications for iOS 10+ devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification) async
  -> UNNotificationPresentationOptions {
  let userInfo = notification.request.content.userInfo

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // ...

  // Print full message.
  print(userInfo)

  // Change this to your preferred presentation option
  // Note: UNNotificationPresentationOptions.alert has been deprecated.
  return [.list, .banner, .sound]
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse) async {
  let userInfo = response.notification.request.content.userInfo

  // ...

  // Print full message.
  print(userInfo)
}

Objective-C

// Receive displayed notifications for iOS 10+ devices.
// Handle incoming notification messages while app is in the foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  NSDictionary *userInfo = notification.request.content.userInfo;

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print full message.
  NSLog(@"%@", userInfo);

  // Change this to your preferred presentation option
  completionHandler(UNNotificationPresentationOptionList |
                    UNNotificationPresentationOptionBanner |
                    UNNotificationPresentationOptionSound);
}

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    NSLog(@"FCM registration token: %@", fcmToken);
    // Notify about received token.
    NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
    [[NSNotificationCenter defaultCenter] postNotificationName:
     @"FCMToken" object:nil userInfo:dataDict];
    // TODO: If necessary send token to application server.
    // Note: This callback is fired at each app startup and whenever a new token is generated.
}

- (void)logFCMToken {
  NSString *fcmToken = [FIRMessaging messaging].FCMToken;
  NSLog(@"Local FCM registration token: %@", fcmToken);

  NSString* displayToken = [NSString stringWithFormat:@"Logged FCM token: %@", fcmToken];

  [[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) {
    if (error != nil) {
      NSLog(@"Error fetching the remote FCM registration token: %@", error);
    } else {
      NSLog(@"Remote FCM registration token: %@", token);
      NSString* message =
        [NSString stringWithFormat:@"FCM registration token: %@", token];
      // display message
      NSLog(@"%@", message);
    }
  }];
  NSLog(@"%@", displayToken);
}

- (void)subsribeToTopic {
  [[FIRMessaging messaging] subscribeToTopic:@"weather"
                                  completion:^(NSError * _Nullable error) {
    NSLog(@"Subscribed to weather topic");
  }];
}

@end

Nếu bạn muốn thêm các thao tác tuỳ chỉnh vào thông báo, hãy đặt click_action tham số trong tải trọng thông báo. Sử dụng giá trị mà bạn sẽ dùng cho khoá category trong tải trọng APNs. Bạn phải đăng ký các thao tác tuỳ chỉnh trước khi có thể sử dụng. Để biết thêm thông tin, hãy xem Hướng dẫn lập trình thông báo cục bộ và từ xa của Apple.

Để nắm được thông tin chi tiết về việc gửi tin nhắn đến ứng dụng của bạn, hãy chuyển đến trang tổng quan DevOps và mức độ tương tác > Nhắn tin > Báo cáo trong bảng điều khiển Firebase. Trang tổng quan này ghi lại số lượng tin nhắn đã gửi và mở trên thiết bị Apple và Android, cùng với dữ liệu về "số lượt hiển thị" (thông báo mà người dùng nhìn thấy) cho ứng dụng Android.

Xử lý thông báo đẩy im lặng

Khi gửi tin nhắn bằng khoá content-available (tương đương với content-available của APNs), tin nhắn sẽ được gửi dưới dạng thông báo im lặng, đánh thức ứng dụng của bạn ở chế độ nền cho các tác vụ như làm mới dữ liệu nền. Không giống như thông báo ở chế độ nền trước, bạn phải xử lý các thông báo này bằng application(_:didReceiveRemoteNotification:fetchCompletionHandler:) phương thức.

Triển khai application(_:didReceiveRemoteNotification:fetchCompletionHandler:) như minh hoạ dưới đây:

Swift

@MainActor
func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
  -> UIBackgroundFetchResult {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // ...

  // Print full message.
  print(userInfo)
  print("Call exportDeliveryMetricsToBigQuery() from AppDelegate")
  Messaging.serviceExtension().exportDeliveryMetricsToBigQuery(withMessageInfo: userInfo)
  return UIBackgroundFetchResult.newData
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired until the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

Nền tảng Apple không đảm bảo việc gửi thông báo ở chế độ nền. Để tìm hiểu về các điều kiện có thể khiến thông báo ở chế độ nền không gửi được, hãy xem tài liệu của Apple về việc Đẩy bản cập nhật ở chế độ nền cho ứng dụng của bạn.

Giải thích tải trọng thông báo

Tải trọng của thông báo là một từ điển gồm các khoá và giá trị. Thông báo được gửi qua APNs có định dạng tải trọng APNs như sau:

  {
    "aps" : {
      "alert" : {
        "body" : "great match!",
        "title" : "Portugal vs. Denmark",
      },
      "badge" : 1,
    },
    "customKey" : "customValue"
  }

Xử lý tin nhắn khi tắt tính năng thay đổi phương thức

Theo mặc định, nếu bạn chỉ định lớp đại diện ứng dụng của ứng dụng cho các thuộc tính đại diện UNUserNotificationCenterMessaging, thì FCM sẽ hoán đổi lớp đại diện ứng dụng để tự động liên kết mã truy cập FCM với mã truy cập APNs của thiết bị và chuyển các sự kiện đã nhận được thông báo đến Analytics. Nếu bạn tắt rõ ràng tính năng thay đổi phương thức, nếu bạn đang xây dựng ứng dụng SwiftUI hoặc nếu bạn sử dụng một lớp riêng biệt cho một trong hai đại diện, thì bạn sẽ cần thực hiện cả hai tác vụ này theo cách thủ công.

Để liên kết mã truy cập FCM với mã truy cập APNs của thiết bị, hãy chuyển mã truy cập APNs đến lớp Messaging trong trình xử lý làm mới mã truy cập của đại diện ứng dụng bằng cách sử dụng thuộc tính apnsToken.

Swift

func application(_ application: UIApplication,
    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  Messaging.messaging().apnsToken = deviceToken;
}

Objective-C

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [FIRMessaging messaging].APNSToken = deviceToken;
}

Để chuyển thông tin biên nhận thông báo đến Analytics, hãy sử dụng phương thức appDidReceiveMessage(_:).

Swift

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
  withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  let userInfo = notification.request.content.userInfo

  Messaging.messaging().appDidReceiveMessage(userInfo)

  // Change this to your preferred presentation option
  completionHandler([[.alert, .sound]])
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
  let userInfo = response.notification.request.content.userInfo

  Messaging.messaging().appDidReceiveMessage(userInfo)

  completionHandler()
}

func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
  fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  Messaging.messaging().appDidReceiveMessage(userInfo)
  completionHandler(.noData)
}

Objective-C

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
      willPresentNotification:(UNNotification *)notification
        withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  NSDictionary *userInfo = notification.request.content.userInfo;

  [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Change this to your preferred presentation option
  completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert);
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
        withCompletionHandler:(void(^)(void))completionHandler {
  NSDictionary *userInfo = response.notification.request.content.userInfo;

  [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  completionHandler();
}

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
  [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
  completionHandler(UIBackgroundFetchResultNoData);
}