首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不被iOS模拟器或物理设备接收的FCM数据消息

不被iOS模拟器或物理设备接收的FCM数据消息
EN

Stack Overflow用户
提问于 2021-09-04 12:55:00
回答 2查看 2.3K关注 0票数 3

我正在从事的一个项目需要使用FCM推送通知&用于VoIP控制的消息等。

问题:

我的iOS物理设备接收推送通知,但是当应用程序处于后台或关闭时,只接收,而在前台时只接收,而不是。此外,它根本不接收任何fcm消息 ( data )通知,例如只包含数据的消息,而没有通知标题/正文的消息,即VoIP状态消息。

我的安装步骤如下(我遵循的详细设置和一般流程可以找到这里):

  1. a (Info.plist) (见这里)
  2. 下载&用Xcode安装GoogleService-Info.plist (参见这里)
  3. 创建密钥,启用推送通知并将.p8文件上载到Firebase (参见这里)
  4. 用Swift代码修改

AppDelegate.swift代码:

代码语言:javascript
复制
import UIKit
import Flutter
import Firebase // this is added, and (see further down)

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure() //add this before the code below
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
  1. capabilities添加到iOS

Info.plist文件功能(后台获取、通知等)

代码语言:javascript
复制
<?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>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    </array>
    ...
    <key>NSCameraUsageDescription</key>
    <string>Allows taking a self-portrait profile image or sending a photo while chating</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Allows using your location to make determining country &amp; location picking easier (optional)</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>Allows using micrphone to chat with someone when making a call</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Allows opening files from gallery</string>
    <key>UIBackgroundModes</key>
    <array>
        <string>audio</string>
        <string>bluetooth-central</string>
        <string>external-accessory</string>
        <string>fetch</string>
        <string>location</string>
        <string>processing</string>
        <string>remote-notification</string>
        <string>voip</string>
    </array>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>FirebaseAppDelegateProxyEnabled</key>
    <false/>
    <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/>
</dict>
</plist>

注意:背景模式(如https://firebase.flutter.dev/docs/messaging/apple-integration/所示)无法启用,而是使用一组复选框启用它们,以启用Background Fetch__等。

  1. FCM -侦听并使用某些通知(显示)服务(如可怕的通知 )显示和通知/消息。

实现遵循以下指导方针

前台消息:

代码语言:javascript
复制
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  print('Got a message whilst in the foreground!');
  ...
});

背景消息:

代码语言:javascript
复制
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();

  print("Handling a background message: ${message.messageId}");
}

void main() {
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(MyApp());
}

问题扩展:

调试时,如果iOS应用程序位于前台/后台,并且向设备发送测试通知或有效的VoIP调用(FCM数据消息),则应用程序从未接收或(所需的断点也未命中)。

是什么原因导致应用程序/iOS不接收这些FCM消息?

从Firebase云函数服务发送的示例VoIP消息:

代码语言:javascript
复制
// build notification on liked status
const payload = {
    token: fcmToken,
    data: {
        uid: context.auth.uid,
        room_id: roomId,
        ...
    },
    android: {
        priority: 'high',
        ttl: 0,
        notification: {
            priority: 'max',
            defaultSound: true,
            defaultVibrateTimings: true,
            sticky: true,
            clickAction: "FLUTTER_NOTIFICATION_CLICK",
        }
    },
    notification: {
        title: `Incoming call from ${name}`,
        body: `Accept/Reject call`,
        // icon: 'your-icon-url',                   // Add profile image URL here if necessary
        // clickAction: 'FLUTTER_NOTIFICATION_CLICK' // required only for onResume or onLaunch callbacks
    },
    apns: {
        payload: {
            aps: {
                category: "NEW_MESSAGE_CATEGORY",
                contentAvailable: true,
            }
        }
    },
    headers: {
        "apns-push-type": "background",
        "apns-priority": "5", // Must be `5` when `contentAvailable` is set to true.
        "apns-topic": "io.flutter.plugins.firebase.messaging", // bundle identifier
    },
};

await admin.messaging().send(payload);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-04 16:26:03

原来的答案(对更多的人更普遍/更有用):

FCM在iOS模拟器上不起作用,所以这是问题解决的一半。对于物理设备,请看一下我在我工作的库中详细编写的一些调试步骤

推通知在iOS上有多种可能出错的方式。当你说:the app never receives,你的意思是你的颤栗应用程序没有收到消息吗?你的设备可能还在接收它们。

  • 在mac上打开Console.app,并开始物理设备的日志记录。过滤器的dasd进程,你可以看到推通知相关的日志,看看你的设备是否拒绝推通知,并没有发送给你的应用程序。最有可能的是,这是一个问题,你如何组织你的信息。
  • 您还可以尝试在Flutterfire firebase_messaging iOS代码中的iOS端调试firebase_messaging方法。表示将意味着应用程序接收到消息。

让我具体回答每一个问题/关切(3):

  1. 我的iOS物理设备只接收推送通知,但只有当应用程序处于后台或关闭时,而不是在前台时。

所以你想在前台显示通知?例如,您需要在Swift中实现userNotificationCenter(_:willPresent:withCompletionHandler:)

代码语言:javascript
复制
    public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        if #available(iOS 14.0, *) {
            completionHandler(.banner)
        } else {
            completionHandler(.alert)
        }
    }

为了在这里帮你多一点,你需要设置你的代表。在上面实现的方法中放置一个断点,以查看它实际上正在被调用。

  • 在Swift:UNUserNotificationCenter.current().delegate = self;
  • 目标-C:UNUserNotificationCenter.currentNotificationCenter.delegate = self;
  1. 此外,它根本不接收任何fcm消息(数据)通知,例如只带有数据的消息,而没有通知标题/正文(即VoIP状态消息)。

如果不设置通知字段,则需要将优先级设置为5,将类型推送到background,将contentAvailable设置为true。不幸的是,您在firebase中使用headers字段是错误的。apns对象应该如下所示,其中标头位于apns中,因为这些是特定于apns的标头:

代码语言:javascript
复制
    apns: {
        headers: {
            "apns-push-type": "background",
            "apns-priority": "5", // Must be `5` when `contentAvailable` is set to true.
            "apns-topic": "io.flutter.plugins.firebase.messaging", // bundle identifier
        },
        payload: {
            aps: {
                category: "NEW_MESSAGE_CATEGORY",
                contentAvailable: true,
            }
        }
    }

如果消息结构错误,您仍然可以在设备上得到一个错误,例如,告诉您优先级为10 (如果没有设置,默认为10 )。由于背景消息(没有通知)不会按照文档传递,所以在Console.app中您应该看到:

代码语言:javascript
复制
CANCELED: com.apple.pushLaunch.com.example.my-example-app-bundle-id:3D8BB6 at priority 10 <private>!

此外,通知的POST请求应该包含具有背景值的apns-push-type标头字段和值为5. - 将后台更新推送到应用程序的apns-优先级字段。

  1. 调试时,如果iOS应用程序位于前台/后台,并且向设备发送测试通知或有效的VoIP调用(FCM数据消息),则应用程序从未接收或(所需的断点也未命中)。是什么原因导致应用程序/iOS不接收这些FCM消息?

这和2号是一样的。

票数 2
EN

Stack Overflow用户

发布于 2021-09-09 16:26:16

呃,试试用AppDelegate来做吧

代码语言:javascript
复制
override func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
  // ADD THIS LINE
  UNUserNotificationCenter.current().delegate = self
        
  GeneratedPluginRegistrant.register(with: self)
  return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

// ADD THIS FUNCTION
override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  // Need to do this or app will eat the notification if app is in foreground
  completionHandler([.alert, .badge, .sound])
}

编辑:注意到Ben的答案仍然适用,推送将无法在模拟器中工作,您必须在物理设备上运行它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69055482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档