Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Hub.Register() Errors in Release, works fine in Debug #171

Open
JoeTomkinson opened this issue Dec 22, 2020 · 4 comments
Open

[BUG] Hub.Register() Errors in Release, works fine in Debug #171

JoeTomkinson opened this issue Dec 22, 2020 · 4 comments

Comments

@JoeTomkinson
Copy link

JoeTomkinson commented Dec 22, 2020

Describe the bug
In a Xamarin Forms project implementing the Azure Notification Hub throws an exception in release mode that it does not exhibit during debugging that causes remote PNS registrations to fail.

Exception or Stack Trace

{
      "JniPeerMembers": {
        "ManagedPeerType": "WindowsAzure.Messaging.NotificationHubException, Xamarin.Azure.NotificationHubs.Android, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
        "JniPeerTypeName": "com/microsoft/windowsazure/messaging/NotificationHubException",
        "JniPeerType": {
          "PeerReference": {
            "Handle": {
              "value": 15194
            },
            "Type": 2,
            "IsValid": true
          },
          "Name": "com/microsoft/windowsazure/messaging/NotificationHubException"
        },
        "InstanceMethods": {},
        "InstanceFields": {},
        "StaticMethods": {},
        "StaticFields": {}
      },
      "StatusCode": 400,
      "StackTrace": "  
      at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, 
      Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <3f19c9fc57a34ac9a473579164f8755e>:0 \n  
      at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, 
      Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <3f19c9fc57a34ac9a473579164f8755e>:0 \n  
      at WindowsAzure.Messaging.NotificationHub.Register (System.String pnsHandle, System.String[] tags) [0x00043] in <15ee46979411457bb0abfed951cc2b1e>:0 \n  
      at NorthNorfolk.Mobile.Client.Droid.Notifications.FirebaseService.SendRegistrationToServer (System.String token) [0x00078] in <f0d16bc144b04854b79558630f62c467>:0 \n  
      --- End of managed WindowsAzure.Messaging.NotificationHubException stack trace 
      
      ---\ncom.microsoft.windowsazure.messaging.NotificationHubException\n\tat 
      com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:254)\n\tat 
      com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:170)\n\tat 
      com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:130)\n\tat 
      com.microsoft.windowsazure.messaging.NotificationHub.upsertRegistrationInternal(NotificationHub.java:446)\n\tat 
      com.microsoft.windowsazure.messaging.NotificationHub.registerInternal(NotificationHub.java:410)\n\tat 
      com.microsoft.windowsazure.messaging.NotificationHub.register(NotificationHub.java:148)\n\tat 
      com.MYAPPNAME.mobile.FirebaseService.n_onNewToken(Native Method)\n\tat 
      com.MYAPPNAME.mobile.FirebaseService.onNewToken(FirebaseService.java:38)\n\tat 
      com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source:86)\n\tat 
      com.google.firebase.iid.zzg.run(Unknown Source:4)\n\tat 
      java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)\n\tat 
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)\n\tat 
      com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:6)\n\tat 
      java.lang.Thread.run(Thread.java:919)\n",
      "JniIdentityHashCode": 19017287,
      "PeerReference": {
        "Handle": {
          "value": 19298
        },
        "Type": 2,
        "IsValid": true
      },
      "Handle": {
        "value": 19298
      },
      "Message": null,
      "Data": {},
      "InnerException": null,
      "Source": "mscorlib",
      "HResult": -2146233088
}

To Reproduce

Simply run the example project for Xamarin Forms focusing on the android platform, switch to release mode and look out for the errors in the logcat.

Code Snippet

FireBaseService in the Android Native project:

 using Android.App;
 using Android.Content;
 using Android.Util;
 using AndroidX.Core.App;
 using Firebase.Messaging;
 using Newtonsoft.Json;
 using Mobile.Client.Configuration;
 using System;
 using System.Linq;
 using WindowsAzure.Messaging;
 using Xamarin.Forms;
 
 namespace Mobile.Client.Droid.Notifications
 {
     [Service]
     [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
     [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
     public class FirebaseService : FirebaseMessagingService
     {
         const string TAG = "FirebaseService";
 
         public override void OnMessageReceived(RemoteMessage message)
         {
             Log.Debug(TAG, "From: " + message.From);
             if (message.GetNotification() != null)
             {
                 //These is how most messages will be received
                 Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
                 SendNotification(message.GetNotification().Body);
             }
             else
             {
                 //Only used for debugging payloads sent from the Azure portal
                 SendNotification(message.Data.Values.First());
             }
         }
 
         public override async void OnNewToken(string token)
         {
             Log.Info(TAG, $"Registration Token: {token}");
             App.Current.Properties["NotificationToken"] = token;
             await App.Current.SavePropertiesAsync();
             SendRegistrationToServer(token);
         }
 
         private void SendNotification(string messageBody)
         {
             var intent = new Intent(this, typeof(MainActivity));
             intent.AddFlags(ActivityFlags.ClearTop);
             var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent);
 
             var notificationChannelName = AppSettingsManager.Settings["NotificationChannelName"];
 
             var notificationBuilder = new NotificationCompat.Builder(this, notificationChannelName);
 
             notificationBuilder.SetContentTitle("Notification")
                         .SetSmallIcon(Resource.Drawable.nndc_logo)
                         .SetContentText(messageBody)
                         .SetAutoCancel(true)
                         .SetAllowSystemGeneratedContextualActions(true)
                         .SetShowWhen(false)
                         .SetContentIntent(pendingIntent);
 
             var notificationManager = NotificationManager.FromContext(this);
 
             notificationManager.Notify(0, notificationBuilder.Build());
 
             MessagingCenter.Send(App.Current, "NotificationRecieved");
         }
 
         private void SendRegistrationToServer(string token)
         {
             try
             {
                 var notificationHubName = AppSettingsManager.Settings["NotificationHubName"];
                 var listenConnectionString = AppSettingsManager.Settings["ListenConnectionString"];
                 var subscriptionTags = AppSettingsManager.Settings["SubscriptionTags"]?.Split(",");
                 var fCMTemplateBody = AppSettingsManager.Settings["FCMTemplateBody"];
 
                 NotificationHub hub = new NotificationHub(notificationHubName, listenConnectionString, this);
                 Log.Info(TAG, $"Created hub object: {hub.NotificationHubPath}");
 
                 // register device with Azure Notification Hub using the token from FCM
                 Registration registration = hub.Register(token, subscriptionTags);
                 Log.Info(TAG, $"Registered token and tags: {registration.PNSHandle}");
 
                 // subscribe to the SubscriptionTags list with a simple template.
                 string pnsHandle = registration.PNSHandle;
                 Log.Info(TAG, $"PNS Handle: {pnsHandle}");
 
                 TemplateRegistration templateReg = hub.RegisterTemplate(pnsHandle, "defaultTemplate", fCMTemplateBody, subscriptionTags);
 
                 Log.Info(TAG, $"Registered template: {templateReg.NotificationHubPath}");
             }
             catch (Exception e)
             {
                 Log.Info(TAG, $"PNS REGISTRATION EXCEPTION: {JsonConvert.SerializeObject(e)}");
                 //Log.Error("DEBUG", $"Error registering device: {e.Message}");
             }
         }
     }
 }

Android Manifest:

<?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.android.mobile" android:installLocation="auto">
  	<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28" />
  	<!--android:extractNativeLibs="true" had to be added below due to a VS/Xamarin Bug: https://github.com/xamarin/xamarin-android/issues/4990-->
  	<application android:label="APPNAME" android:icon="@mipmap/icon" android:extractNativeLibs="true" android:roundIcon="@mipmap/icon_round">
  		<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
  		<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
          <action android:name="com.google.android.c2dm.intent.RECEIVE" />
          <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
          <category android:name="${applicationId}" />
        </intent-filter>
  		</receiver>
  	</application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
  
    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
    <uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" />
  
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  	<uses-permission android:name="android.permission.USE_FINGERPRINT" />
  	<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
  	<uses-permission android:name="android.permission.USE_BIOMETRIC" />
  	<uses-permission android:name="android.permission.BLUETOOTH" />
  </manifest>

Expected behavior

I would expect this to register the device with the notification hub and be visible as a registration in Service Bus Explorer.

Setup (please complete the following information):

  • OS: Ran against Android OS 10 (SDK 29) primarily.
  • IDE : Visual Studio : Version 16.8.1
  • Version of the Library used:
    Xamarin.Azure.NotificationHubs.Android
    Version: 1.1.3
@JoeTomkinson JoeTomkinson changed the title [BUG] [BUG] Hub.Register() Errors in Release, works fine in Debug Dec 22, 2020
@marstr
Copy link
Member

marstr commented Dec 24, 2020

Howdy - I've seen reports of similar issues. In those cases, the Xamarin.Android Release profile was using a code shrinker that was more (read: too) aggressive than the Debug profile. To see if this is your issue, you'll need to ensure that the proguard configuration file is setup to not strip out anything in the com.microsoft.windowsazure.messaging.notificationhubs namespace. Something like:

-keep class com.microsoft.windowsazure.messaging.notificationhubs.** { <init>(***); }

@JoeTomkinson
Copy link
Author

Howdy - I've seen reports of similar issues. In those cases, the Xamarin.Android Release profile was using a code shrinker that was more (read: too) aggressive than the Debug profile. To see if this is your issue, you'll need to ensure that the proguard configuration file is setup to not strip out anything in the com.microsoft.windowsazure.messaging.notificationhubs namespace. Something like:

-keep class com.microsoft.windowsazure.messaging.notificationhubs.** { <init>(***); }

Apologies for a slow reply. I'll look to try this today; as far as I was aware however I don't believe I had a code shrinker set on the release build. But it wouldn't surprise me if there was something strange going on under the hood of the release build so I'll investigate further and report back.

@JoeTomkinson
Copy link
Author

So I actually set the R8 shrinker to run as it was set to blank, that's produced the following error:

{
  "JniPeerMembers": {
    "ManagedPeerType": "WindowsAzure.Messaging.NotificationHubException, Xamarin.Azure.NotificationHubs.Android, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
    "JniPeerTypeName": "com/microsoft/windowsazure/messaging/NotificationHubException",
    "JniPeerType": {
      "PeerReference": {
        "Handle": {
          "value": 17866
        },
        "Type": 2,
        "IsValid": true
      },
      "Name": "com/microsoft/windowsazure/messaging/NotificationHubException"
    },
    "InstanceMethods": {},
    "InstanceFields": {},
    "StaticMethods": {},
    "StaticFields": {}
  },
  "StatusCode": 400,
  "StackTrace": "  at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <3f19c9fc57a34ac9a473579164f8755e>:0 \n  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <3f19c9fc57a34ac9a473579164f8755e>:0 \n  at WindowsAzure.Messaging.NotificationHub.Register (System.String pnsHandle, System.String[] tags) [0x00043] in <254d369ec5544bb1b606035994077f91>:0 \n  at NorthNorfolk.Mobile.Client.Droid.Notifications.FirebaseService.SendRegistrationToServer (System.String token) [0x00078] in <4b8b745c15df475a92a1855a0ba61d95>:0 \n  --- End of managed WindowsAzure.Messaging.NotificationHubException stack trace ---\ncom.microsoft.windowsazure.messaging.NotificationHubException\n\tat com.microsoft.windowsazure.messaging.Connection.executeRequest(Unknown Source:146)\n\tat com.microsoft.windowsazure.messaging.Connection.executeRequest(Unknown Source:134)\n\tat com.microsoft.windowsazure.messaging.Connection.executeRequest(Unknown Source:7)\n\tat com.microsoft.windowsazure.messaging.NotificationHub.upsertRegistrationInternal(Unknown Source:22)\n\tat com.microsoft.windowsazure.messaging.NotificationHub.registerInternal(Unknown Source:48)\n\tat com.microsoft.windowsazure.messaging.NotificationHub.register(Unknown Source:27)\n\tat crc64d75b20eac0c397e9.FirebaseService.n_onNewToken(Native Method)\n\tat crc64d75b20eac0c397e9.FirebaseService.onNewToken(Unknown Source:0)\n\tat com.google.firebase.messaging.FirebaseMessagingService.handleIntent(Unknown Source:53)\n\tat com.google.firebase.messaging.EnhancedIntentService.lambda$processIntent$0$EnhancedIntentService(Unknown Source:1)\n\tat com.google.firebase.messaging.EnhancedIntentService$$Lambda$0.run(Unknown Source:6)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)\n\tat com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:7)\n\tat java.lang.Thread.run(Thread.java:764)\n",
  "JniIdentityHashCode": 196544507,
  "PeerReference": {
    "Handle": {
      "value": 18122
    },
    "Type": 2,
    "IsValid": true
  },
  "Handle": {
    "value": 18122
  },
  "Cause": null,
  "Message": null,
  "Data": {},
  "InnerException": null,
  "Source": "mscorlib",
  "HResult": -2146233088
}

I can see that there's a reference to a status code this time and a 400 error. Any thoughts on what could be causing that because as far as I know this is all set up exactly as it should be based on the Microsoft documentation.

@JoeTomkinson
Copy link
Author

Also not sure if it's relevant but while looking at logcat I get the following warning just after the above error:

A connection to https://[Our Azure Notification Hub name].servicebus.windows.net/ was leaked. Did you forget to close a response body?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants