Search code examples
azurexamarin.formsandroid-notificationsazure-notificationhubfirebase-notifications

How to troubleshoot: Android client not receiving Azure Notifications Hub messages, but does receive test messages sent from Firebase Console


I'm trying to set up a Xamarin.Forms Android client app to receive push notifications from my Azure C# backend. My GCMListenerService.OnMessageReceived() method is not triggered when I send a message from my backend using SendGcmNativeNotificationAsync(...), although the result return success/"Enqueued". I'm successfully receiving windows notifications from the same server event.

My GCMListenerService.OnMessageReceived() method IS triggered when I send a test message from the Firebase Console, but NOT when I send a test message from the Azure Console -> Notification Hubs area (portal says successfully sent).

I can confirm that my client receives a registration token from Firebase and has Google Play Services available. I'm testing on a physical device, not an emulator.

Any suggestions on the next steps to troubleshoot this? Not sure what to try next.

I'm using Log.Debug statements in GCMListenerService.OnMessageReceived() to determine if a message has been received or not.

Thanks for any help!


Solution

  • I got it working. I didn't realise that the Android app needed to register with the Notifications Hub; which is silly in retrospect.

    Usually this is taken care of by the Xamarin Component GoogleCloudMessagingClient used by all the walkthroughs, but I didn't want to use that component because I'm learning and wanted to see the boilerplate code.

    For anyone else taking this approach, here are the things I needed to add (this isn't copy-paste code to use, just demonstrates my missing link):

    var cs = ConnectionString.CreateUsingSharedAccessKeyWithListenAccess(
          new Java.Net.URI("sb://YOUR-SERVICE-BUS.servicebus.windows.net/"),
          "YOUR-KEY"); // you can get these two values from Azure Console -> Your NotificationHub -> Settings -> Access Policies
    
        var hubName = "your-hub-name"; //the name of your Notification Hub resource on Azure
    
        hub = new NotificationHub(hubName, cs, context); //create the hub (this class is in WindowsAzure.Messaging namespace, which is accessible after you add the Azure Messaging component to your android project)
    
        hub.Register(registrationId, "YOUR_TAG"); //tag can be anything (alphanumeric, -, _, no spaces)
        //hub.Register registers this device and its registrationId (from cloud messaging) to the Notifications Hub.
    

    This is in addition to all the other things you need to do as per all the official walkthroughs. I'll list them here as someone may find it helpful.

    List of Steps, Google for Details

    Firebase:

    1. Create new project + setup push notifications

    Azure:

    1. Create the Notifications Hub
    2. Supply Notifications Hub with Server Key from Firebase project settings

    Android Client Project:

    1. Add Xamarin.GooglePlayServices.GCM via NuGet
    2. Add Azure Messaging component (right click Components in project explorer, click "Get More Components")
    3. Add the following permissions to AndroidManifest.xml:
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <permission android:name="[YOUR PACKAGE NAME HERE].permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="[YOUR PACKAGE NAME HERE].permission.C2D_MESSAGE" />
    
    1. In MainActivity, check if Google Play Services are available.
    2. If so, create a RegistrationIntentService service to register the client device with Firebase Cloud Messaging
    3. Start this service in the MainActivity onCreate() method
    4. Implement an InstanceIDListenerService service (for if the app registrationID changes, Google easily for details)
    5. Implement a GcmListenerService service for receiving and reacting to cloud messages (Google easily for details)
    6. Declare your three services in AndroidManifest.xml, for example the GcmListenerService as follows (Google easily for more details):
    <application android:label="YOUR_APP_NAME">
        <receiver android:name="com.google.android.gms.gcm.GcmReceiver" 
                  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="[YOUR APP PACKAGE NAME HERE]" />
            </intent-filter>
        </receiver>
    
      </application>
    

    If using Xamarin you can simply use the Service attribute instead of editing AndroidManifest.xml, which will add the required declarations to the manifest for you, e.g.

    [Service(Exported = false)]
    class RegistrationIntentService : IntentService
    {
    
    1. Create the NotificationHub instance and register the unique token / registrationID Firebase returned for the device (as per the code at the start of this post, e.g. my missing link).