2
votes

We are using Azure Mobile Services to Push notifications to a Xamarin Android and a Xamarin iOS and a Windows Universal App. The Windows Universal App has plenty of documentation around what we need, although we haven’t had a chance to implement it yet. However, both Xamarin Android and iOS are missing all documentation around Push Notifications. If you go to http://azure.microsoft.com/en-us/documentation/services/mobile-services/ and select Xamarin Android or Xamarin iOS and .NET Backend there are zero links for documentation around these APIs. After digging around a ton yesterday I found this: http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-push/ and http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-push/ both which were last updated in September of last year. The documentation was promised to be updated over 5 months ago.

When I use the Xamarin Component from Microsoft for Azure Mobile Services: http://components.xamarin.com/view/azure-mobile-services/ I am able to get the MobileServiceClient up and running, but not the Push notifications.

The API:

Push pushManager = MobileService.GetPush();
string deviceId = "what is this???";
//Option 1:
pushManager.RegisterNativeAsync(deviceId);
//Option 2:
GcmRegistration googleNotificationRegistration = new GcmRegistration(deviceId);
pushManager.RegisterAsync(googleNotificationRegistration);

Documentation I’m using:

My question is simple: What is deviceId supposed to be? And how do I get it?

All the documentation above is for Winodws Universal Apps not for Xamarin Apps on Mono.

In the writing up of this question I have found articles about "Get Started with Notification Hubs":

Are these the example I should be using? They look old and the Android one mentions nothing about Azure Mobile Services. Should I not even be using the Azure Mobile Services Xamarin Component for Android?

1

1 Answers

3
votes

tl;dr

deviceId should be just the GCMRegistrationId.


I looked into the source code of the implementations of the component DLLs and also Android SDKs.

Firstly, let's take a look to your option 1 and option 2 behind the scene. Basically both eventually do the same job of creating a GcmRegistration and passing it the internal RegistrationManager.

    public Task RegisterAsync (Registration registration)
    {
        if (registration == null) {
            throw new ArgumentNullException ("registration");
        }
        if (string.IsNullOrWhiteSpace (registration.PushHandle)) {
            throw new ArgumentNullException ("registration.deviceId");
        }
        return this.RegistrationManager.RegisterAsync (registration);
    }

    public Task RegisterNativeAsync (string deviceId, IEnumerable<string> tags)
    {
        if (string.IsNullOrWhiteSpace (deviceId)) {
            throw new ArgumentNullException ("deviceId");
        }
        GcmRegistration registration = new GcmRegistration (deviceId, tags);
        return this.RegistrationManager.RegisterAsync (registration);
    }

Then, one of the API calls that I can find involving the Registration.PushHandle (which is the deviceId you passed) is as below

    public async Task<IEnumerable<Registration>> ListRegistrationsAsync (string deviceId)
    {
        MobileServiceHttpResponse mobileServiceHttpResponse = await this.client.HttpClient.RequestAsync (HttpMethod.Get, string.Format ("/push/registrations?deviceId={0}&platform={1}", new object[] {
            Uri.EscapeUriString (deviceId),
            Uri.EscapeUriString (Platform.Instance.PushUtility.GetPlatform ())
        }), this.client.CurrentUser, null, true, null, MobileServiceFeatures.None);
        return JsonConvert.DeserializeObject<IEnumerable<Registration>> (mobileServiceHttpResponse.Content, new JsonConverter[] {
            new RegistrationConverter ()
        });
    }

I have then switched to Android Mobile Services SDK to look for similar code to find some hints. Sadly, it is found called pnsHandle in android but still no hints what it is.

    /**
     * Registers the client for native notifications with the specified tags
     * @param pnsHandle PNS specific identifier
     * @param tags  Tags to use in the registration
     * @return  The created registration
     * @throws Exception
     */
    public Registration register(String pnsHandle, String... tags) throws Exception {
        if (isNullOrWhiteSpace(pnsHandle)) {
            throw new IllegalArgumentException("pnsHandle");
        }

        Registration registration = PnsSpecificRegistrationFactory.getInstance().createNativeRegistration(mNotificationHubPath);
        registration.setPNSHandle(pnsHandle);
        registration.setName(Registration.DEFAULT_REGISTRATION_NAME);
        registration.addTags(tags);

        return registerInternal(registration);
    }

Finally, I guess the below example code from http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-push/#update-app should be calling the same API which now explain everything, i.e. deviceId is just the GCMRegistrationId.

    @Override
    public void onRegistered(Context context,  final String gcmRegistrationId) {
        super.onRegistered(context, gcmRegistrationId);

        new AsyncTask<Void, Void, Void>() {

            protected Void doInBackground(Void... params) {
                try {
                    ToDoActivity.mClient.getPush().register(gcmRegistrationId, null);
                    return null;
                }
                catch(Exception e) { 
                    // handle error             
                }
                return null;            
            }
        }.execute();
    }