如何能够在 iOS 上使用 FCM 接收后台通知(android 已经有效)

How to be able to receive background notifications with FCM on iOS (android already works)

在我的 Flutter 应用中,管理员用户可以通过 FCM 向其他用户发送通知。在 android 中已经有效,但在 iOS 中通知仅在打开应用程序时到达。我已经在互联网上尝试了很多东西,但仍然无法正常工作。

这是管理推送的 dart 代码:

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}


class PushNotificationsManager {

  PushNotificationsManager._();

  factory PushNotificationsManager() => _instance;

  static final PushNotificationsManager _instance = PushNotificationsManager
      ._();

  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  final NotificationPlugin _notificationPlugin = NotificationPlugin();

  Future<void> init() async {
    if (Platform.isIOS) {
      _firebaseMessaging.requestNotificationPermissions(
          IosNotificationSettings());
    }
    _firebaseMessaging.configure(
      // Called when the app is in the foreground and we receive a push notif.
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: ${message}");
        print(message['notification']['body']);
        _notificationPlugin.showNotification(
            title: 'TEST',
            content: message['notification']['body']
        );
        //sendNotification();
      },
      // Called when the app has been closed completely and its opened
      // from the notification directly

      //onBackgroundMessage: Platform.isAndroid ? myBackgroundMessageHandler:null,
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        if(Platform.isIOS){
          message = _modifyNotificationJson(message);
        }
      },
      // Called when the app is in the background and its opened from the notif
      onResume: (Map<String, dynamic> message) async {
        print("onMessage: ${message}");
        if(Platform.isIOS){
          message = _modifyNotificationJson(message);
        }
      },
    );

  }

  Map _modifyNotificationJson(Map<String, dynamic> message) {
    message['data'] = Map.from(message ?? {});
    message['notification'] = message['aps']['alert'];
    return message;
  }


  Future sendNotification(String body, String title) async {
    final String url = 'https://fcm.googleapis.com/fcm/send';
    var notification;
    notification =
    '{"notification": {"body": "${body}", "title": "${title}", "content_available": "true", "click_action": "FLUTTER_NOTIFICATION_CLICK"}, "priority": "high", "to": "MYTOPIC"}';
    final response = await http.post(
        url,
        headers: <String, String>{
          "Content-Type": "application/json",
          "Keep-Alive": "timeout=5",
          "Authorization": "key=MYKEY"
        },
        body: notification
    );

    print(response.body);
  }
}

AppDelegate.swift:

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    if #available(iOS 10.0, *) {
      // For iOS 10 display notification (sent via APNS)
      UNUserNotificationCenter.current().delegate = self

      let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
      UNUserNotificationCenter.current().requestAuthorization(
        options: authOptions,
        completionHandler: {_, _ in })
    } else {
      let settings: UIUserNotificationSettings =
      UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
      application.registerUserNotificationSettings(settings)
    }

    application.registerForRemoteNotifications()
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}


我已经在 xcode 中启用了 pushNotifications 和后台模式,已经检查了我的证书,但问题仍然存在。有人可以帮助我吗?

尝试将此添加到您的 info.plist

<key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string>

然后从 Firebase 控制台发送测试通知。看看能不能用。

删除 appdelegate.swift didFinishLaunchingWithOptions 方法中的所有内容,只保留下面两行。

GeneratedPluginRegistrant.register(with: self)

return super.application(application, didFinishLaunchingWithOptions: launchOptions)

请求 fcm 插件的许可,看看后台通知现在是否显示。

删除以下代码会阻止任何前台通知,这是默认行为,您可以使用叠加层来显示前台通知。

if #available(iOS 10.0, *) {
  // For iOS 10 display notification (sent via APNS)
  UNUserNotificationCenter.current().delegate = self
}