Handle with clicked notification when app is closed (killed)

RafaelAddessoRafaelAddesso BRMember ✭✭
edited February 22 in Xamarin.iOS

Hi all,

I developed an app that receive some notifications (i am using FirebasePushNotificationManager plugin).

When my app is in background, i receive the notification normally and i am able to open a specific page using notification data on CrossPushNotification.Current.OnNotificationOpened event.

But when my app is forced closed, i receive the notification but this event is not raised, and my app open on mainpage.

Is there any idea of what i am doing wrong?

Some code below:

AppDelegate.cs

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

            FirebasePushNotificationManager.Initialize(launchOptions,true);
            CrossFirebasePushNotification.Current.RegisterForPushNotifications();

            LoadApplication(new App());

            CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
            {
                UIApplication.SharedApplication.ApplicationIconBadgeNumber = UIApplication.SharedApplication.ApplicationIconBadgeNumber + 1;
            };
            CrossFirebasePushNotification.Current.OnNotificationAction += (s, p) =>
            {
                if (!string.IsNullOrEmpty(p.Identifier))
                {
                    System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}");
                    foreach (var data in p.Data)
                    {
                        System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
                    }
                }
            };
            CrossPushNotification.Current.OnNotificationOpened += (s, p) =>
            {
                foreach (var data in p.Data)
                {
                    if (data.Key == "aps.category")
                    {
                        App.NotificationId = data.Value.ToString();
                    }
                    System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
                }
            };

            return base.FinishedLaunching(application, launchOptions);
        }
        public override void WillEnterForeground(UIApplication uiApplication)
        {
            base.WillEnterForeground(uiApplication);
        }

        public override void OnActivated(UIApplication uiApplication)
        {
            base.OnActivated(uiApplication);
        }

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

        public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
        {
            System.Diagnostics.Debug.WriteLine("FailedToRegisterForRemoteNotifications");
            FirebasePushNotificationManager.RemoteNotificationRegistrationFailed(error);
        }

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

                completionHandler(UIBackgroundFetchResult.NewData);

                NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
                var notificationTitle = (aps[new NSString("title")] as NSString).ToString();
                System.Console.WriteLine("title: " + notificationTitle);
                var clickAction = (aps[new NSString("ClickAction")] as NSString).ToString();
                System.Console.WriteLine("ClickAction: " + clickAction);
                var notificationMessage = (aps[new NSString("job_id")] as NSString).ToString();
                System.Console.WriteLine("job_id: " + notificationMessage);
                var NotificationId = (aps[new NSString("notification_id")] as NSString).ToString();
                System.Console.WriteLine("notification_id: " + NotificationId);

                if (UIApplication.SharedApplication.ApplicationState.Equals(UIApplicationState.Active))
                {
                    System.Console.WriteLine("Quando esta aberto: " + NotificationId);
                }
                else
                {
                    App.Current.MainPage = new BetaChatPage(clickAction);

                }
                // Do your magic to handle the notification data
                System.Console.WriteLine(userInfo);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine("Error: " + ex.Message);

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

App.cs Firebase definitions:

CrossFirebasePushNotification.Current.OnTokenRefresh += (s, p) =>
                    {
                        System.Diagnostics.Debug.WriteLine($"TOKEN : {p.Token}");
                    };
                    CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
                    {
            string strCategory = string.empty;
                         foreach (var data in p.Data)
                        {
                            if (data.Key == "aps.category")
                            {
                                string strCategory = data.Value.ToString();
                            }
                            System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
                        }
                                await App.Current.MainPage.Navigation.PushPopupAsync(new CategoryPage(strCategory));
                    };
                    CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
                    {
            string strCategory = string.empty;
                        System.Diagnostics.Debug.WriteLine("Opened");
                        foreach (var data in p.Data)
                        {
                            if (data.Key == "aps.category")
                            {
                               strCategory = data.Value.ToString();
                            }
                            System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
                        }

                        if (!string.IsNullOrEmpty(p.Identifier))
                        {
                            System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}");
                        }
                        if (!String.IsNullOrEmpty(strArtist))
                        {
                            MainPage = new CustomNavigationViewPage(new MasterPage("CategoryPage", strCategory));
                        }
                    };
                    CrossFirebasePushNotification.Current.OnNotificationDeleted += (s, p) =>
                    {
                        System.Diagnostics.Debug.WriteLine("Deleted");
                    };

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    Try to remove all your CrossFirebase code in your iOS project(except the initialized configuration code), place the OnNotificationReceived and OnNotificationOpened events only in your App.cs's OnStart lifecycle event. You can analyze the user info using this event's p.Data.
    The OnNotificationOpened will be triggered when a user clicks the notification even though the app is on the quitted state.
    From your code, if strArtist is empty your app's MainPage won't be changed. Maybe this could cause your issue. You can test the push behavior directly without the logic code to see the effect:

    CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
    {
        string strCategory = string.empty;
        System.Diagnostics.Debug.WriteLine("Opened");
        //foreach (var data in p.Data)
        //{
        //    if (data.Key == "aps.category")
        //    {
        //        strCategory = data.Value.ToString();
        //    }
        //    System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
        //}
    
        //if (!string.IsNullOrEmpty(p.Identifier))
        //{
        //    System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}");
        //}
        //if (!String.IsNullOrEmpty(strArtist))
        //{
        MainPage = new CustomNavigationViewPage(new MasterPage("CategoryPage", strCategory));
        //}
    };
    
  • RafaelAddessoRafaelAddesso BRMember ✭✭
    Hi LandLu!

    Thank you very much for your answer but it is not working yet. When app is closed and the notifistio. Is received, the event OnNotificationOpened is not raised, only when app is in background.
  • LakshyaLakshya Member ✭✭✭

    @RafaelAddesso Did you find any solution?

  • RafaelAddessoRafaelAddesso BRMember ✭✭
    edited May 6

    Hi @Aswathy !

    Yes, i could solve this by adding the following code to FinishedLaunching:

    if (launchOptions != null && launchOptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
                    {
    
                        NSDictionary notification = launchOptions.ObjectForKey(UIApplication.LaunchOptionsRemoteNotificationKey) as NSDictionary;
                        if (notification != null)
                        {
                            NSDictionary aps = notification[new NSString("aps")] as NSDictionary;
                            var clickAction = (aps[new NSString("category")] as NSString).ToString();
                            LoadApplication(new App("OpenChat", clickAction));
    
                        }
                        else
                        {
                            LoadApplication(new App());
                        }
                    }
                    else
                    {
                        LoadApplication(new App());
                    }
    

    So the final version of my function is:

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
            {
                try
                {
                    global::Xamarin.Forms.Forms.Init();
                    FirebasePushNotificationManager.Initialize(launchOptions, true);
                    CrossFirebasePushNotification.Current.RegisterForPushNotifications();
    
                    if (launchOptions != null && launchOptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
                    {
    
                        NSDictionary notification = launchOptions.ObjectForKey(UIApplication.LaunchOptionsRemoteNotificationKey) as NSDictionary;
                        if (notification != null)
                        {
                            NSDictionary aps = notification[new NSString("aps")] as NSDictionary;
                            var clickAction = (aps[new NSString("category")] as NSString).ToString();
                            LoadApplication(new App("OpenChat", clickAction));
                        }
                        else
                        {
                            LoadApplication(new App());
                        }
                    }
                    else
                    {
                        LoadApplication(new App());
                    }
            //Other initializations
    
    
                }
                catch (Exception ex)
                {
            //any log function
                }
                return base.FinishedLaunching(application, launchOptions);
            }
    

    Hope this help you. If you need anything else please let me know to try to help you.

Sign In or Register to comment.