Deepak yogi
Deepak yogi

Reputation: 117

FCM Notification not receive in foreground using xamarin forms

I have been integrating push notification using firebase in Xamarin. I have created developer provisioning profile and also generated P12 file and attach in Firebase console project.

I am sending notification from cloud messaging(From FCM Console project), the notification receives when the app is closed, if I started the app then send a notification, the notification not receive.

This is Firebase initialisation

     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);

In my case fist condition is true (if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))) and notification registration successfully

and the RegisteredForRemoteNotifications method called every time when I debug the app

When i send notification from cloud messaging the DidReceiveRemoteNotification callled but notification not show(comes)in foreground if application closed(background) notification comes

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);
    }

Can anyone suggest something helpful?

Thanks in advance!

Upvotes: 0

Views: 1863

Answers (2)

Deepak yogi
Deepak yogi

Reputation: 117

I resolved issue that not received notification in Foreground. I implemented a class NotificationDelegate then inherit this class by UNUserNotificationCenterDelegate After that create methods for handle notification in Foreground 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

Then did code for register notofication in server

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);
        }

Then create registration method in AppDelegate class

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

The important think if you using Debug Mode in this case

FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Sandbox);

and in Entitlements.plist add this

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

if you using Release Mode in this case

FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Production);

and in Entitlements.plist add this

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

Upvotes: 0

FreakyAli
FreakyAli

Reputation: 16572

For devices running iOS 9 and below, override AppDelegate's DidReceiveRemoteNotification method to handle notifications received when the client app is in the foreground, and all data messages that are sent to the client. A message is a dictionary of keys and values:

public override void DidReceiveRemoteNotification (UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
   // Do your magic to handle the notification data
   System.Console.WriteLine (userInfo);
}

For iOS 10 devices and above, implement IUNUserNotificationCenterDelegate interface and override WillPresentNotification method to handle notifications received when the client app is in the foreground:

// 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);
}

Upvotes: 1

Related Questions