PMARSH
PMARSH

Reputation: 167

DidReceiveRemoteNotification never called in Xamarin.iOS

I'm trying to implement push notifications for my iOS application using Xamarin and the Xamarin.Firebase.iOS.CloudMessaging package.

I've got everything setup and working i,e. When the application is in the foreground I can receive notifications (containing and not containing the "content-available" tag) and interact with them (tapping the notification etc.)

However, when the application is in the background, I receive the notifications but, no callbacks are called. To my understanding, the "didReceiveRemoteNotification" should be called when:

  1. The application is in the foreground regardless of if the "content-available" tag is enabled
  2. If the application is in the background or suspended, with the "content-available" tag enabled
  3. When the user taps on the notification

Here are the functions I've implemented in my AppDelegate.cs:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    global::Xamarin.Forms.Forms.Init();
    Firebase.Core.App.Configure();
    FireBaseRegistration();
    return base.FinishedLaunching(app, options);
}


private void FireBaseRegistration()
{
    // 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;
    }
    else
    {  
        // iOS 9 or before
        var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
        var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
        UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
    }

    //Register for APNs notifications
    UIApplication.SharedApplication.RegisterForRemoteNotifications();

    Messaging.SharedInstance.Delegate = this;

    var token = InstanceId.SharedInstance.Token;
    Debug.WriteLine(token);

    //////Connect to FCM (Only used for Foreground notifications)
    Messaging.SharedInstance.ShouldEstablishDirectChannel = true;

    // Monitor token generation
    InstanceId.Notifications.ObserveTokenRefresh((sender, e) => {
        // Note that this callback will be fired everytime a new token is generated, including the first
        // time. So if you need to retrieve the token as soon as it is available this is where that
        // should be done.
        token = InstanceId.SharedInstance.Token;
        Console.WriteLine(token);

    });

}


//Register APNs token because method swizzling is de-activated
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    Console.WriteLine("Registered for remote notifications");
    Console.WriteLine(deviceToken.GetBase64EncodedString(NSDataBase64EncodingOptions.None));
    Console.WriteLine(deviceToken);
}



[Export("messaging:didReceiveMessage:")]
public void DidReceiveMessage(Messaging messaging, RemoteMessage remoteMessage)
{
    // Do your magic to handle the notification data
    Console.WriteLine("iOS 11 Foreground");
}


//Shows local notification and is called when user taps notification
[Export("userNotificationCenter:DidReceiveRemoteNotification:withCompletionHandler:")]
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
    Console.WriteLine("Received a notficaiton");
    completionHandler(UIBackgroundFetchResult.NewData);
}

//To receive notifications in foreground on iOS 11 devices.
[Export("userNotificationCenter:willPresent:withCompletionHandler:")]
public void WillPresent(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
    Console.WriteLine("Handling iOS 11 foreground notification");
    completionHandler(UNNotificationPresentationOptions.Sound | UNNotificationPresentationOptions.Alert);
}

////Called when tapping notification
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
    Console.WriteLine("Handling push notificaiton interaction");
    completionHandler();
}

//Receive data message on iOS 10 devices.
public void ApplicationReceivedRemoteMessage(RemoteMessage remoteMessage)
{
    Console.WriteLine("Handling iOS 10 data message notification");
}   

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

I've tried these out on iOS 10.3.3 and iOS 11.2. Here are the functions called for both versions:

  1. When the application is in the foreground
    • On iOS 10.3.3: WillPresentNotification() (with and without the "content-available" tag)
    • On iOS 11.2: WillPresentNotification() (with and without the "content-available" tag)
  2. When the application is in the background:
    • On iOS 10.3.3: nothing Shoudln't it be DidReceiveRemoteNotification?
    • On iOS 11.2: nothing Shoudln't it be DidReceiveRemoteNotification?

I have the remote-notificaitons and background fetch background modes activated in my Info.plist file.

Packages info:

Remarks:

The DidReceiveMessage function is implemented in the Xamarin sample but, in my case, is never called.

The DidReceiveNotificationResponse is called when the user taps on the notificaiton.

The WillPresent is also never called.

I've tried with notifications via the firebase API and directly via the APNs (with the pusher application).

Upvotes: 2

Views: 3539

Answers (1)

Serega
Serega

Reputation: 650

Set Messaging.SharedInstance.ShouldEstablishDirectChannel=false and send data-only messages.

Upvotes: 2

Related Questions