使用 xamarin 表单在前台未收到 FCM 通知

Posted

技术标签:

【中文标题】使用 xamarin 表单在前台未收到 FCM 通知【英文标题】:FCM Notification not receive in foreground using xamarin forms 【发布时间】:2019-08-05 11:43:52 【问题描述】:

我一直在 Xamarin 中使用 firebase 集成推送通知。我已经创建了开发人员配置文件,还生成了 P12 文件并附加在 Firebase 控制台项目中。

我正在从云消息传递(来自 FCM 控制台项目)发送通知,当应用程序关闭时会收到通知,如果我启动应用程序然后发送通知,则不会收到通知。

这是 Firebase 初始化

     LoadApplication(new App());

            if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
            
                UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
                                                                        (granted, error) =>
                                                                        
                                                                            if (granted)
                                                                                InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
                                                                        );
            
            else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
            
                var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
                        UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
                        new NSSet());

                UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
                UIApplication.SharedApplication.RegisterForRemoteNotifications();
            
            else
            
                UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
                UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
            

//FirebasePushNotificationManager.Initialize(launchOptions,true);
            return base.FinishedLaunching(uiApplication, launchOptions);

在我的情况下,第一个条件为真(if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)))并且通知注册成功

以及每次调试应用程序时调用的 RegisteredForRemoteNotifications 方法

当我从云消息发送通知时,DidReceiveRemoteNotification 被调用,但如果应用程序关闭(后台)通知来,通知不会在前台显示(来)

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    
        FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Sandbox);
    

    public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
    
        FirebasePushNotificationManager.RemoteNotificationRegistrationFailed(error);

    
    // To receive notifications in foregroung on ios 9 and below.
    // To receive notifications in background in any iOS version
    public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
    
        // 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.

        // If you disable method swizzling, you'll need to call this method. 
        // This lets FCM track message delivery and analytics, which is performed
        // automatically with method swizzling enabled.
        FirebasePushNotificationManager.DidReceiveMessage(userInfo);
        // Do your magic to handle the notification data
        System.Console.WriteLine(userInfo);

        completionHandler(UIBackgroundFetchResult.NewData);
    

    public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
    
        base.ReceivedRemoteNotification(application, userInfo);
    



    // To receive notifications in foreground on iOS 10 devices.
    [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
    public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    
        // Do your magic to handle the notification data
        System.Console.WriteLine(notification.Request.Content.UserInfo);
    


    public void ApplicationReceivedRemoteMessage(RemoteMessage remoteMessage)
    
        Console.WriteLine(remoteMessage.AppData);
    

谁能推荐一些有用的东西?

提前致谢!

【问题讨论】:

这是当您的应用程序在后台时的推送通知行为,然后只有设备接收推送通知。 你好 @KiShOrE 当应用程序处于前台时,此 DidReceiveRemoteNotification 方法不会调用。 【参考方案1】:

对于运行 iOS 9 及更低版本的设备,重写 AppDelegate 的 DidReceiveRemoteNotification 方法以处理客户端应用在前台时收到的通知,以及发送到客户端的所有数据消息。消息是键和值的字典:

public override void DidReceiveRemoteNotification (UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)

   // Do your magic to handle the notification data
   System.Console.WriteLine (userInfo);

对于 iOS 10 及以上设备,实现 IUNUserNotificationCenterDelegate 接口并重写 WillPresentNotification 方法来处理客户端应用在前台时收到的通知:

// To receive notifications in foreground on iOS 10 devices.
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)

  // Do your magic to handle the notification data
  System.Console.WriteLine(notification.Request.Content.UserInfo);



 public void ApplicationReceivedRemoteMessage(RemoteMessage remoteMessage)

    Console.WriteLine(remoteMessage.AppData);

【讨论】:

你好@hakim 我遇到了新问题,我实现了 IUNUserNotificationCenterDelegate 接口,然后第一次收到的通知都是forground and background,但第二次都没有收到调试通知是forground and background 您可能想查看 iOS 本地通知并使用代码创建自己的通知! google.com/url?sa=t&source=web&rct=j&url=https://… @FreakyAli 兄弟。我可以在我的 xamarin.ios 应用程序中接收通知。但是 DidReceiveRemoteNotification 从来没有命中。我的操作系统是 12.4.1 。你能看看这个问题***.com/questions/62673761/…【参考方案2】:

我解决了在Foreground 中未收到通知的问题。 我实现了一个类NotificationDelegate 然后通过UNUserNotificationCenterDelegate 继承这个类 之后在前台 iOS 10 中创建处理通知的方法

 public class NotificationDelegate : UNUserNotificationCenterDelegate
   
    public NotificationDelegate()
    
    

    public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    
        // Do something with the notification
        Console.WriteLine("Active Notification: 0", notification);

        // Tell system to display the notification anyway or use
        // `None` to say we have handled the display locally.
        completionHandler(UNNotificationPresentationOptions.Alert|UNNotificationPresentationOptions.Sound);
    


    public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
    
        // Take action based on Action ID
        switch (response.ActionIdentifier)
        
            case "reply":
                // Do something
                break;
            default:
                // Take action based on identifier
                if (response.IsDefaultAction)
                
                    // Handle default action...
                
                else if (response.IsDismissAction)
                
                    // Handle dismiss action
                
                break;
        
        completionHandler();
    
  





I am facing this issue(not receive notification in foreground) because in WillPresentNotification method i am sending only UNNotificationPresentationOptions.Alert (completionHandler(UNNotificationPresentationOptions.Alert);) but both alert and sound are required for notification in Foreground and Background in iOS 10

然后在服务器中进行注册通知的代码

public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
        
            global::Xamarin.Forms.Forms.Init();

if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
            
                UNUserNotificationCenter center = UNUserNotificationCenter.Current;

                center.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Badge, (bool arg1, NSError arg2) =>
                
                    if (arg1)
                        InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);

                );

                center.Delegate = new NotificationDelegate();
            
            else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
            

                var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());

                UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

            

            return base.FinishedLaunching(uiApplication, launchOptions);
        

然后在 AppDelegate 类中创建注册方法

 public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
        
            FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Sandbox);
         

如果你在这种情况下使用Debug Mode,重要的是考虑

FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Sandbox);

在 Entitlements.plist 中添加这个

<plist version="1.0">
<dict>
    <key>aps-environment</key>
    <string>development</string>
</dict>
</plist>

如果你在这种情况下使用Release Mode

FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Production);

在 Entitlements.plist 中添加这个

<plist version="1.0">
<dict>
    <key>aps-environment</key>
    <string>production</string>
</dict>
</plist>

【讨论】:

以上是关于使用 xamarin 表单在前台未收到 FCM 通知的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 表单:使用 FCM 推送通知

推送通知未在 Android 前台显示

在 IOS 中未收到 FCM 推送通知。而应用程序在后台或终止。我使用 FirebaseMessaging 6.0.9 Pub

使用 react-native-firebase 在 Android 中关闭应用程序时未收到 fcm 消息

Android - 包含 click_action 后未收到 FCM 推送通知

Android 应用在收到新的 FCM 消息时崩溃(前台和后台)