0

I am sending Firebase Notification on devices with Xamarin plugin. This is my configuration : Visual Studio 2022. iOS 15. Xcode 13. All is working fine in Android devices. All is working fine in Apple devices except one thing : When the application is in background, the notification is received only when the user open the application.

Here is my code :

public class MVision : UIApplicationDelegate, IUNUserNotificationCenterDelegate, IMessagingDelegate
        {
             public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions){
     Firebase.Core.App.Configure();
                //    Messaging.SharedInstance.Self
                //    Messaging.messaging().delegate = self
                Messaging.SharedInstance.Delegate = (IMessagingDelegate)Self;
                if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
                {
                    // Request Permissions
                    UNUserNotificationCenter.Current.RequestAuthorization(
                         UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
                         (granted, error) =>
                         {
                     // Do something if needed
                 });
    
                    // For iOS 10 display notification (sent via APNS)
                    UNUserNotificationCenter.Current.Delegate = new MyUNUserNotificationCenterDelegate();
    
                    // For iOS 10 data message (sent via FCM)
                    Messaging.SharedInstance.Delegate = this;
                }
                else
                {
                    // iOS 9 or before
                    var allNotificationTypes = UIUserNotificationType.Alert
                     | UIUserNotificationType.Badge
                     | UIUserNotificationType.Sound;
                    var settings = UIUserNotificationSettings
                     .GetSettingsForTypes(allNotificationTypes, null);
                    UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
                }
       Messaging.SharedInstance.ShouldEstablishDirectChannel = true;
                UNUserNotificationCenter.Current.Delegate = new MyUNUserNotificationCenterDelegate();
    
                UIApplication.SharedApplication.RegisterForRemoteNotifications();

The methods are :

    [Export("messaging:didReceiveRegistrationToken:")]
    public void DidReceiveRegistrationToken(Messaging messaging, string fcmToken)
    {
        var i = 1;
    //    var token = Messaging.SharedInstance.FcmToken;

        // TODO: If necessary send token to application server.
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }

       [Export("messaging:didRegisterForRemoteNotificationsWithDeviceToken:")]
       public void DidRegisterForRemoteNotificationsWithDeviceToken(UIKit.UIApplication application, Foundation.NSData deviceToken) {
           Messaging.SharedInstance.ApnsToken = deviceToken;
   }

    public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { var userInfo1 = userInfo; }


    [Export("application:didReceiveNotificationResponse:fetchCompletionHandler:")]
    public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, System.Action completionHandler)
    {
        completionHandler();
    }


    [Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")]
    public override void DidReceiveRemoteNotification(
    UIApplication application,
    NSDictionary userInfo,
    System.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.
        // Except if "content-available" is set to true / 1

        // Print full message.
     //   Console.WriteLine(userInfo);

        completionHandler(UIBackgroundFetchResult.NewData);
    }

    [Export("messaging:didReceiveMessage:")]
    public void DidReceiveMessage(Messaging messaging, RemoteMessage remoteMessage)
    {
        var notification = (NSDictionary)remoteMessage.AppData.ValueForKey(new NSString("notification"));
        var title = notification.ValueForKey(new NSString("title"));
        var text = notification.ValueForKey(new NSString("body"));
    //    remotenotification = true;
        ScheduleNotification(title.ToString(), text.ToString());
    }

    //This code is for showing notification
    void ScheduleNotification(string title, string body)
    {
        // Create content
        var content = new UNMutableNotificationContent();
        content.Title = title;
        //content.Subtitle = "Subtitle";
        content.Body = body;
        content.Badge = 1;
        content.CategoryIdentifier = "notification_fv";
        content.Sound = UNNotificationSound.Default;

        // Fire trigger in one seconds
        var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(1, false);

        var requestID = "customNotification";
        var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);

        //                      This is the line that does the trick

        UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) => {
            if (err != null)
            {
                // Report error
                System.Console.WriteLine("Error: {0}", err);
            }
            else
            {
                // Report Success
                System.Console.WriteLine("Notification Scheduled: {0}", request);
            }
        });
    }

    /*     [Export("messaging:didReceiveMessage:")]
         public void DidReceiveMessage(Messaging messaging, RemoteMessage remoteMessage)
         {
             // Handle Data messages for iOS 10 and above.
             HandleMessage(remoteMessage.AppData);
             var fcmToken = Messaging.SharedInstance.FcmToken;

         }*/


    [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
    public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, System.Action<UNNotificationPresentationOptions> completionHandler)
    {
        SystemSound.Vibrate.PlayAlertSound();
        SystemSound.Vibrate.PlaySystemSound();
        completionHandler(UNNotificationPresentationOptions.Alert);
    }

The notification center delegate class is :

using Foundation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIKit;
using UserNotifications;

namespace MVision.iOS
{
    public class MyUNUserNotificationCenterDelegate : UNUserNotificationCenterDelegate
    {
        bool toggle;
        public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
        {
            if (toggle)
                completionHandler(UNNotificationPresentationOptions.Alert);
            else
            {
                //     Console.WriteLine(notification);
                //    completionHandler(UNNotificationPresentationOptions.None);
                completionHandler(UNNotificationPresentationOptions.Alert);
            }
            toggle = !toggle;
        }
    }
}

I check the info.plist

<key>UIBackgroundModes</key>
<array>
    <string>remote-notification</string>
</array>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>FirebaseScreenReportingEnabled</key>
<true/>

I also refer to entitlement.developer.plist :

<dict>
    <key>aps-environment</key>
    <string>development</string>
</dict>

I also parameter my notification with content-available = 1 and mutable-content = 1.

I think that the problem is that "DidReceiveRemoteNotification" is never call neither in background, nor in foreground. Any Ideas ?

Please also notice : In Xamarin, when you stay in Visual Studio 2019 and you pass to iOS 15, you will not have simulators anymore, please download Visual Studio 2022. Entitlement.plist does not work on this configuration. You must create Entitlement.developer.plist and refer to is.

C Morell
  • 81
  • 1
  • 3
  • 10
  • This link(https://stackoverflow.com/questions/38450595/firebase-cloud-messaging-ios-no-background-push-notification) may help you, and which nuget package are you using? – Wen xu Li Nov 18 '21 at 09:44
  • I already saw this link, but the problem is that didRegisterForRemoteNOtificationsWithDeviceToken is not called too. I am using Xamarin.Firebase.iOS.CloudFirestore 1.19.0 and Xamarin.Firebase.iOS.CloudMessaging 4.7.1 – C Morell Nov 18 '21 at 16:13
  • Setting content_available, priority and mutable_content do not change anything. – C Morell Nov 18 '21 at 16:17
  • Would you mind sharing us a baisc, minimal project to test ? You can upload it to github and attach the link here. – Wen xu Li Nov 22 '21 at 09:40

0 Answers0