April 24th, 2017

Implementing Push Notifications in Your Android Apps

An important feature of almost every app is the ability to support push notifications. With push notifications, you can update your users without requiring the app to run at all times or having it poll a server, potentially running down the battery. With the introduction of Firebase Cloud Messaging (FCM), Google made it a little bit easier to implement push notifications in Android apps. FCM is the new and improved version of Google Cloud Messaging (GCM) that you can use to send remote notifications to your client app. For apps that will be targeting multiple platforms or need to take advantage of advanced push operations (like segmented push), we can use FCM with Azure Notification Hubs.

Unlike GCM, FCM takes care of most of the underlying messaging plumbing for you. With FCM, you no longer have to write code to register your app or include retry logic to update subscription tokens. You can add basic FCM push notifications to your app by doing the following:

  1. Install a couple of Xamarin.Android NuGets and a credentials file.
  2. Add a couple of <service> declarations to your AndroidManifest.xml.
  3. Write a few lines of code to pull it all together.

Also, instead of writing a test program to send notifications, you can use the new web-based Firebase Console to send test notifications to your app.

Today, we’ll take a look at how to use the Xamarin.Firebase.Messaging package to build FCM-based push notification features into your app.

Set Up Firebase Cloud Messaging

Before you can use FCM services in your app, you have to create a Firebase Project in the Firebase Console. After you log in, click CREATE NEW PROJECT, enter a project name, and click CREATE PROJECT:

Next, click Add Firebase to your Android app. When prompted, enter the package name for your app and click REGISTER APP:


When you click REGISTER APP, credentials are automatically generated for your app to access Firebase servers. These credentials are packaged in a file called google-services.json, which is automatically downloaded after you click the REGISTER APP button. Save this file, as you’ll need it later!

Add Packages to Your Project

Next, you’ll need to add two Xamarin NuGet packages to your app. Start the NuGet Package Manager (in Visual Studio, right-click References in the Solution Explorer and select Manage NuGet Packages), browse for Xamarin.GooglePlayServices.Base, select it, and click Install.

The Google Play Services package must be installed in order for FCM to work. Next, do the same for Xamarin.Firebase.Messaging:

Extra dependency packages will be installed for each of these packages.

Also, make sure that you have the Google Play Services APK installed on your Android device. Firebase Messaging uses the Google Play Services APK to communicate with Firebase servers.

Add the Google Services JSON File to Your Project

When you created a new project in the Firebase Console, you downloaded a google-services.json credentials file–it’s time to plug that file into your app!

Copy google-services.json to your project folder and add it to your project (in Visual Studio, you can click the Show All Files icon in the Solution Explorer, right-click google-services.json, then select Include in Project).

Save changes and close the Solution. Re-open the Solution and set the Build Action for google-services.json to GoogleServicesJson (in Visual Studio, the Build Action pull-down menu is in the Advanced section of the Properties pane):

Now that google-services.json is part of your project, the Xamarin build process can extract the credentials and merge them into the generated AndroidManifest.xml file. Xamarin.Firebase.Messaging uses these credentials to access Firebase services.

Add an Instance ID Receiver

Your client app has to first register with FCM before it can receive push notifications. The way this works is that Xamarin.Firebase.Messaging contacts FCM, sends it credentials, and gets back a registration token. This token, which is updated on a regular basis, is used to create a secure channel to Firebase servers. You can also forward this token to your app server so that it can communicate with Firebase.

Your client app must implement a FirebaseInstanceIdService to handle the creation and updating of registration tokens. This is actually a lot simpler than it sounds, as you’ll see next.

Declare the Instance ID Receiver in the Android Manifest

Edit AndroidManifest.xml (under Properties in the Solution Explorer) and insert the following <receiver> elements into the <application> section:



    
        
        
        
    

This declares the necessary receivers that will be used for managing registration tokens.

Add Internet Permissions

If your app does not already have the INTERNET permission enabled, enable it under Properties > Android Manifest > Required permissions:

Implement the Firebase Instance ID Service

Now it’s time to write some code! Add a new C# file to your project (in Visual Studio, right click your project name and select Add > New Item > Class). Give it the name MyFirebaseIIDService.cs and input the following code:

using System;
using Android.App;
using Firebase.Iid;
using Android.Util;

namespace FCMExample
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class MyFirebaseIIDService : FirebaseInstanceIdService
    {
        const string TAG = "MyFirebaseIIDService";
        public override void OnTokenRefresh()
        {
            var refreshedToken = FirebaseInstanceId.Instance.Token;
            Log.Debug(TAG, "Refreshed token: " + refreshedToken);
        }
    }
}

Change the namespace FCMExample above to the namespace of your app.

That’s all there is to it!

The OnTokenRefresh method is invoked when the registration token is created or changed. Because the token is logged to the Output window whenever it’s updated, you’ll be able to see it while the app is running. You’ll enter this token into the Firebase Console when you’re ready to send a test notification to your app.

Try it!

Now that your app has enough functionality to receive background notifications from FCM, it’s time for a test drive. Before you build your app, make sure that its package name matches the package name that you entered into the Firebase Console when you created your Firebase project.

Rebuild the app, run it, and watch the Output window until the token is displayed. For example:

Copy this token to the clipboard; you’ll paste it into the Firebase Console in the next step.

Send a Message

Sign in to the Firebase Console, select your project, click Notifications, and click SEND YOUR FIRST MESSAGE:

On the Compose message page, enter in a message under Message text. Select Single device as the target and paste in the registration token that you copied from the IDE Output window:

Before you click SEND MESSAGE, background your app (you can tap the Android overview button and touch the home screen). Click SEND MESSAGE in the Firebase Console when you’re ready. When the Review message dialog is displayed, click SEND. The notification icon should appear on the Android device:

Open the notification to view the message; the notification message should be exactly what you typed into the Firebase Console:

Congratulations, you’ve just sent and received your first FCM push notification!

Learn More

This simple example only touches the surface of what you can do with FCM and push notifications using Visual Studio. To learn more about Firebase Cloud Messaging with Xamarin.Android for Visual Studio and other platforms, be sure to read Firebase Cloud Messaging and Remote Notifications with Firebase Cloud Messaging. The FCMNotifications sample app is also a good place to borrow code from if you’re building an app that uses FCM push notifications.

Author

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Nick Turner

    The receiver’s section is blank. I noticed that this happens on James M’s blogs also

    • AlanW

      I used this to make notifications working:
      <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" />
      <category android:name="YOUR_PACKAGE_NAME" />
      </intent-filter>
      </receiver>
      https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceIdReceiver

      Read more