locked
Notification hub to specific device RRS feed

  • Question

  • User205936 posted

    I am following this tutorial to test out notification hub for android and it works https://docs.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm

    but I need to finish the user registration process and get the userid so I can use the userid as tag to register on Azure Notification hub. So instead of doing the registration right away in MainAcitivty.cs, I just save the token in database.

    so instead of having this

    public override void OnNewToken(string token) { Log.Debug(TAG, "FCM token: " + token); SendRegistrationToServer(token); }

    i have this public override void OnNewToken(string token) { Log.Debug(TAG, "FCM token: " + token); LocalDb.InsertDeviceToken(token); }

    when the whole registration process is finished, I have following in an acitivty.cs

    var notificationUtil = new NotificationUtil(); notificationUtil.SendRegistrationToServer(this.ApplicationContext);

    following is the code for NotificationUtil.cs

    ``` using System; using System.Collections.Generic; using Android.Util; using PantAppLib.source.dbaccess; using PantAppLib.source.models; using WindowsAzure.Messaging;

    namespace PantAppAndroid.Utils { public class NotificationUtil { public void SendRegistrationToServer(Android.Content.Context context) { try { // Register with Notification Hubs NotificationHub hub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString, context); var userProfile = LocalDb.GetUserProfile(); if (userProfile != null) { var tags = new List() { userProfile.Id }; var token = LocalDb.GetDeviceToken().TokenValue; Registration registration = hub.Register(token, tags.ToArray()); var regID = registration.RegistrationId;

                    Log.Debug("MyFirebaseMsgService", $"Successful registration of ID {regID}");
    
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
    

    } ```

    I can only guess that I am using the correct context object here, and when I run the code, i hit on following exception

    {Android.OS.NetworkOnMainThreadException: Exception of type 'Android.OS.NetworkOnMainThreadException' was thrown. at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <42748fcc36b74733af2d9940a8f3cc8e>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <42748fcc36b74733af2d9940a8f3cc8e>:0 at WindowsAzure.Messaging.NotificationHub.Register (System.String pnsHandle, System.String[] tags) [0x00043] in <7ef3a358b177460dacd73e56198bd8f2>:0 at PantAppAndroid.Utils.NotificationUtil.SendRegistrationToServer (Android.Content.Context context) [0x00041] in C:\Users\weiha\source\repos\App2\PantAppAndroid\Utils\NotificationUtil.cs:36 --- End of managed Android.OS.NetworkOnMainThreadException stack trace --- android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513) at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117) at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105) at java.net.InetAddress.getAllByName(InetAddress.java:1154) at com.android.okhttp.Dns$1.lookup(Dns.java:39) at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175) at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141) at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83) at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174) at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126) at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95) at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281) at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127) at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89) at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:26) at com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:213) at com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:170) at com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:130) at com.microsoft.windowsazure.messaging.NotificationHub.refreshRegistrationInformation(NotificationHub.java:301) at com.microsoft.windowsazure.messaging.NotificationHub.registerInternal(NotificationHub.java:399) at com.microsoft.windowsazure.messaging.NotificationHub.register(NotificationHub.java:148) at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method) at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30) at android.view.View.performClick(View.java:6597) at android.view.View.performClickInternal(View.java:6574) at android.view.View.access$3100(View.java:778) at android.view.View$PerformClick.run(View.java:25885) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) }

    the follow up tutorial - Send notifications to specific devices is not for xamarin android, I am not sure why you have this kind of content structure where you have 3 tutorials, where the second is built upon the first, but they are using totally different tech. Any help?

    Tuesday, September 29, 2020 8:11 PM

Answers

  • User369979 posted

    Yes, wrap the registration code with task run.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, September 30, 2020 8:22 AM

All replies

  • User369979 posted

    When it is registered in the FirebaseMessagingService it was run on the secondary thread instead of the main UI thread. So please wrap the code with: await Task.Run(() => { // your register code here... }); This could trigger the registration in the thread.

    Wednesday, September 30, 2020 6:16 AM
  • User205936 posted

    Hi Lu

    thanks for the reply, the error occurs at this line and this happens outside of FirebaseMessagingService Registration registration = hub.Register(token, tags.ToArray());

    and you mean following should work?

    ``` await Task.Run(() => {

    Registration registration = hub.Register(token, tags.ToArray());
    

    }); ```

    Wednesday, September 30, 2020 8:16 AM
  • User369979 posted

    Yes, wrap the registration code with task run.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, September 30, 2020 8:22 AM
  • User205936 posted

    thanks a lot Lu, now i have verified that message can reach specific device using azure notification hub test send

    Thursday, October 1, 2020 7:12 PM