HabibAli / FCM-Xamarin-Forms

Many peoples are concerned about adding FCM to their android project under Xamarin Forms. The firebase library doesn't get installed under xamarin forms due to version issue of Android support lib in xamarin forms. So here is the workaround
MIT License
35 stars 11 forks source link

Background Notifications don't show in iOS #8

Open Enoges opened 7 years ago

Enoges commented 7 years ago

Platform: iOS 10.2+ Problem: When I send a notification from FireBase console or from my code calling FireBase. My iPhones don't receive the background notifications(as a bubble). But, if I had the application in foreground, I received the notification as a "DisplayAlert" from the function ApplicationReceivedRemoteMessage(RemoteMessage remoteMessage).

So, the device is registered on FCM, the device have the token, the device can receive the notifications, but the device didnt receive the notifications on background.

In VisualStudio 2017 at .iOS project manifest I have the Background mode activated and the remote notifications activated too

¿It's this a common issue? ¿Can I solve for working at my project?

Code of AppDelegate `

[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IUNUserNotificationCenterDelegate, IMessagingDelegate
{
    protected SQLiteAsyncConnection conn;
    //
    // This method is invoked when the application has loaded and is ready to run. In this 
    // method you should instantiate the window, load the UI into it and then make the window
    // visible.
    //
    // You have 17 seconds to return from this method, or iOS will terminate your application.
    //
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        global::Xamarin.FormsMaps.Init();
        CachedImageRenderer.Init();
        LoadApplication(new App());

        UITabBar.Appearance.SelectedImageTintColor = UIColor.FromRGB(139, 194, 77);
        UINavigationBar.Appearance.TintColor = UIColor.FromRGB(139,194,77);

        CrossVersionTracking.Current.Track();

        // Firebase component initialize
        Firebase.Analytics.App.Configure();

        // Register your app for remote notifications.
        if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
        {
            // iOS 10 or later
            var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
            UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => {
                Console.WriteLine(granted);
            });

            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.Current.Delegate = this;

            // For iOS 10 data message (sent via FCM)
            Messaging.SharedInstance.RemoteMessageDelegate = this;
        }
        else
        {
            // iOS 9 or before
            var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
            var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
            UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
        }

        UIApplication.SharedApplication.RegisterForRemoteNotifications();

        Firebase.InstanceID.InstanceId.Notifications.ObserveTokenRefresh((sender, e) =>
                    {

                        newToken = Firebase.InstanceID.InstanceId.SharedInstance.Token;

                        //Conectamos con la base de datos.
                        database = new SQLiteClient();
                        conn = database.GetConnection();

                   usuario = null;
                        try
                        {
                            var task = Task.Run(async () =>
                            {
                                usuario = await conn.Table<Usuario>()
                                   .FirstOrDefaultAsync();
                            });
                            task.Wait();
                            if (usuario != null)
                            {
                                usuario.token = newToken;
                                task = Task.Run(async () =>
                                {
                                    await conn.InsertOrReplaceAsync(usuario);
                                });
                                task.Wait();
                            }
                        }
                        catch (Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine("TOKEN ERROR\tNo se ha podido Guardar el Token" + ex.Message);
                        }

                        System.Diagnostics.Debug.WriteLine("TOKEN\t" + newToken);

                        connectFCM();
                    });

        #endregion
        return base.FinishedLaunching(app, options);
    }

    public override void DidEnterBackground(UIApplication uiApplication)
    {
        Messaging.SharedInstance.Disconnect();
        Console.WriteLine("Disconnected from FCM");
    }

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

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        #if DEBUG
        Firebase.InstanceID.InstanceId.SharedInstance.SetApnsToken(deviceToken, Firebase.InstanceID.ApnsTokenType.Sandbox);
        #endif
        #if RELEASE
        Firebase.InstanceID.InstanceId.SharedInstance.SetApnsToken(deviceToken, Firebase.InstanceID.ApnsTokenType.Prod);
        #endif
    }
    // iOS 9 <=, fire when recieve notification foreground
    public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
    {
        Messaging.SharedInstance.AppDidReceiveMessage(userInfo);

        // Generate custom event

        NSString[] keys = { new NSString("Event_type") };
        NSObject[] values = { new NSString("Recieve_Notification") };
        var parameters = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(keys, values, keys.Length);

        // Send custom event
        Firebase.Analytics.Analytics.LogEvent("CustomEvent", parameters);

        if (application.ApplicationState == UIApplicationState.Active)
        {
            System.Diagnostics.Debug.WriteLine(userInfo);
            var aps_d = userInfo["aps"] as NSDictionary;
            var alert_d = aps_d["alert"] as NSDictionary;
            var body = alert_d["body"] as NSString;
            var title = alert_d["title"] as NSString;
            debugAlert(title, body);
        }

    }

    // iOS 10, fire when recieve notification foreground
    [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
    public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    {
        System.Console.WriteLine(notification.Request.Content.UserInfo);
        var title = notification.Request.Content.Title;
        var body = notification.Request.Content.Body;
        debugAlert(title, body);
    }

    private void connectFCM()
    {
        Console.WriteLine("connectFCM\tEjecutandose la función.");
        Messaging.SharedInstance.Connect((error) =>
        {
            if (error == null)
            {
                //TODO: Change Topic to what is required
                Messaging.SharedInstance.Subscribe("/topics/all");
            }
            //System.Diagnostics.Debug.WriteLine("connectFCM\t" + (error != null ? "error occured" : "connect success"));
            Console.WriteLine("connectFCM\t" + (error != null ? "error occured" + error.DebugDescription : "connect success"));

        });
    }
    private void debugAlert(string title, string message)
    {
        var alert = new UIAlertView(title ?? "Title", message ?? "Message", null, "Cancel", "OK");
        alert.Show();
    }

    public void ApplicationReceivedRemoteMessage(RemoteMessage remoteMessage)
    {
        Console.WriteLine("\n*******************************************");
        Console.WriteLine("AplicationReceivedRemoteMessage\t" + remoteMessage.AppData);
        Console.WriteLine("\n*******************************************");
        var title = remoteMessage.AppData.ValueForKey(new NSString("title"));
        var text = remoteMessage.AppData.ValueForKey(new NSString("text"));
        debugAlert("" + title,  "" + text);
    }

    [Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
    public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
    {
        debugAlert("DidreceiveNotificationResponse", response + ""  );
    }

`

Thanks a lot for your time.

FernandoMrq commented 6 years ago

Can you help me? In my app, agência i putfirebase.analytics.app.configure() i give : app nota exists in analytics

HabibAli commented 6 years ago

The notification must be rolling out from top when your app is in background. Did you notice?