android - FCM 后台通知适用于 Android;不在 iOS 中

标签 android ios flutter firebase firebase-cloud-messaging

我正在开发一个带有 Firebase messaging 的 flutter 应用程序涉及。该应用程序适用于 iOS 和 Android。
在 Android 版本中,我可以很好地获取数据消息,并且 Firebase Messaging 后台监听器运行良好。每次发送消息时都会触发后台监听器。
然而,在 iOS 中,后台监听器永远不会被解雇。但是,如果我使用 notification 发送推送通知包含的部分则默认通知由 SDK 显示,在后台消息监听器中仍然没有任何 react 。
阅读了很多问题,我想很多人都面临过这个问题。下面是我的代码。
Main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp();

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  FirebaseMessaging.instance
        .getInitialMessage()
        .then((RemoteMessage? message) {
      developer.log("REMOTE MESSAGE");
      if (message != null) {
        developer.log(message.data.toString());
      }
    });

  FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
    RemoteNotification? notification = message.notification;
    AndroidNotification? android = message.notification?.android;
    developer.log("REMOTE MESSAGE LISTENER");
    if (message.data["data_type"] == "TEXT") {
      await AwesomeNotifications().createNotification(
        content: NotificationContent(
            id: UniqueKey().hashCode,
            groupKey: message.data["senderUid"],
            channelKey: 'basic_channel',
            title: message.data["title"],
            body: message.data["body"],
            summary: message.data["body"], // Anything you want here
            notificationLayout: NotificationLayout.Messaging,
            displayOnBackground: true,
            displayOnForeground: true),
      );
    } else if (message.data["data_type"] == "IMAGE") {
      await AwesomeNotifications().createNotification(
        content: NotificationContent(
            id: UniqueKey().hashCode,
            groupKey: message.data["senderUid"],
            channelKey: 'basic_channel',
            title: message.data["title"],
            body: Emojis.art_framed_picture + " " + message.data["body"],
            summary: message.data["body"], // Anything you want here
            notificationLayout: NotificationLayout.Messaging,
            displayOnBackground: true,
            displayOnForeground: true),
      );
    }
  });

  //Request permission for firebase messaging

  NotificationSettings settings =
      await FirebaseMessaging.instance.requestPermission(
    alert: true,
    announcement: false,
    badge: true,
    carPlay: false,
    criticalAlert: false,
    provisional: false,
    sound: true,
  );

  print('User granted permission: ${settings.authorizationStatus}');

  /// Update the iOS foreground notification presentation options to allow
  /// heads up notifications.
  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );

  AwesomeNotifications().initialize('resource://drawable/logo', [
    NotificationChannel(
        channelGroupKey: 'basic_tests',
        channelKey: 'basic_channel',
        channelName: 'Basic notifications',
        channelDescription: 'Notification channel for basic tests',
        defaultColor: Color(0xFF9D50DD),
        ledColor: Colors.white,
        importance: NotificationImportance.High),
  ]);

  runApp(MultiProvider(
    child: MyApp(),
  ));
}
AppDeligate.swift
import UIKit
import Flutter
import GoogleMaps
import FirebaseMessaging

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
      GMSServices.provideAPIKey("xxxxxxx-xxxx")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    
    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

       Messaging.messaging().apnsToken = deviceToken
       super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
     }

}
pubspec.yaml
name: project
description: A new Flutter project.

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"



dependencies:
  intl: ^0.17.0

  firebase_auth: ^3.1.0
  firebase_core: ^1.6.0
  firebase_messaging: ^11.4.1
  cloud_firestore:  ^3.1.9
  firebase_storage: ^10.2.8
  awesome_notifications: ^0.6.21

dependency_overrides:
  firebase_messaging_platform_interface: ^3.5.1
  firebase_crashlytics_platform_interface: 3.1.13
  cloud_firestore_platform_interface: 5.4.13
  firebase_auth_platform_interface: 6.1.11
  firebase_storage_platform_interface: 4.0.14
  cloud_functions_platform_interface: 5.0.21
  firebase_analytics_platform_interface: 3.0.5
  firebase_remote_config_platform_interface: 1.0.5
  firebase_dynamic_links_platform_interface: 0.2.0+5
  firebase_performance_platform_interface: 0.1.0+5
  firebase_app_installations_platform_interface: 0.1.0+6

dev_dependencies:
  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/graphics/
    - assets/icons_chat/
    - assets/lottie/
 
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>customer</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>$(FLUTTER_BUILD_NAME)</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>$(FLUTTER_BUILD_NUMBER)</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIViewControllerBasedStatusBarAppearance</key>
    <false/>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Use your device location to find nearby sellers</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Use your device location to find nearby sellers</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Use your device location to find nearby sellers</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Take image from your gallery</string>
    <key>NSCameraUsageDescription</key>
    <string>Take image from your gallery</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>Take image from your gallery</string>
    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>remote-notification</string>
    </array>
    <key>GoogleUtilitiesAppDelegateProxyEnabled</key>
    <false/>
    <key>FirebaseAppDelegateProxyEnabled</key>
    <false/>
    <key>CADisableMinimumFrameDurationOnPhone</key>
    <true/>
</dict>
</plist>
正如您在此处看到的,我已启用 Background FetchRemote Notifications也是。
在为 iOS 设置 firebase 设置时,我一直遵循我的设置 - https://firebase.flutter.dev/docs/messaging/apple-integration/#3-generating-a-provisioning-profile .这意味着向 Firebase 注册 APN key ,注册 App 标识符(XCode 生成了正确的标识符并且我正在使用它),甚至生成了一个预置配置文件(但是我正在使用 XCode 托管预置配置文件)。无论如何,我没有生成任何特定的证书,因为它已经由 XCode 完成。
以下是我的flutter doctor结果
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.1, on macOS 12.4 21F79 darwin-arm, locale
    en-LK)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[!] Xcode - develop for iOS and macOS (Xcode 13.4.1)
    ! CocoaPods 1.10.1 out of date (1.11.0 is recommended).
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin
        code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To upgrade see
      https://guides.cocoapods.org/using/getting-started.html#installation for
      instructions.
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[✓] VS Code (version 1.67.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability
这是我的 JSON 通知数据
"message": {

    "token": recieverFcm,
    "data": {
        "title": senderName,
        "body": message,
        "chatRoomId": chatRoomId,
        "sender_profile_pic": senderProfilePic,
        "senderUid": senderUid,
        "data_type": messageType,
        "click_action": "OPEN_CHAT_ROOM"
    },
    "android": {
        "priority": "high"
    },
    "apns": {
        "payload": {
            "aps": {
                "category": "OPEN_CHAT_ROOM",
                "sound": "enable",
                "content-available": 1,
            },
            "data": {
                "title": senderName,
                "body": message,
                "chatRoomId": chatRoomId,
                "sender_profile_pic": senderProfilePic,
                "senderUid": senderUid,
                "data_type": messageType,
                "click_action": "OPEN_CHAT_ROOM"
            },
        }
    }
}
在上面的 Json 我有 2 data部分仅用于测试。我已经测试过,删除它们中的任何一个都不会产生任何影响。
我该如何解决这个问题?

最佳答案

确保您在 XCODE 的签名和功能部分下选择了后台模式下的远程通知和后台获取
enter image description here

关于android - FCM 后台通知适用于 Android;不在 iOS 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72644505/

相关文章:

ios - 如何像 start_test_server_in_background( :timeout => 30)

flutter - textDirection != null assert is not null ListTile

sharedpreferences - Flutter Shared Preferences 保存值,不显示

function - self 更新的 Flutter 模型

java - 如何在不使用android :configChanges的情况下让ExoPlayer在设备旋转时恢复视频播放

android - 如何在 Android 中抑制 "Loud music may harm your hearing..."警告

android - Android 中的 ViewPager + RecyclerView 问题

java - XmlPullParser 获取子节点的首选方式?

更新时覆盖 iOS 应用程序支持目录文件?

ios - 如何仅在 ScrollView 中禁用滚动而不在内容 View 中禁用滚动?