title | description | services | documentationcenter | author | manager | editor | ms.assetid | ms.service | ms.workload | ms.tgt_pltfrm | ms.devlang | ms.topic | ms.date | ms.author |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Add push notifications to your Xamarin.Forms app | Microsoft Docs |
Learn how to use Azure services to send multi-platform push notifications to your Xamarin.Forms apps. |
app-service\mobile |
xamarin |
conceptdev |
crdun |
d9b1ba9a-b3f2-4d12-affc-2ee34311538b |
app-service-mobile |
mobile |
mobile-xamarin |
dotnet |
article |
10/12/2016 |
crdun |
[!INCLUDE app-service-mobile-selector-get-started-push]
In this tutorial, you add push notifications to all the projects that resulted from the Xamarin.Forms quick start. This means that a push notification is sent to all cross-platform clients every time a record is inserted.
If you do not use the downloaded quick start server project, you will need the push notification extension package. For more information, see Work with the .NET backend server SDK for Azure Mobile Apps.
For iOS, you will need an Apple Developer Program membership and a physical iOS device. The iOS simulator does not support push notifications.
[!INCLUDE app-service-mobile-configure-notification-hub]
[!INCLUDE app-service-mobile-update-server-project-for-push-template]
Complete this section to enable push notifications for the Xamarin.Forms Droid project for Android.
[!INCLUDE notification-hubs-enable-firebase-cloud-messaging]
[!INCLUDE app-service-mobile-android-configure-push]
With the back end configured with FCM, you can add components and codes to the client to register with FCM. You can also register for push notifications with Azure Notification Hubs through the Mobile Apps back end, and receive notifications.
- In the Droid project, right-click References > Manage NuGet Packages ....
- In the NuGet Package Manager window, search for the Xamarin.Firebase.Messaging package and add it to the project.
- In the project properies for the Droid project, set the app to compile using Android version 7.0 or higher.
- Add the google-services.json file, downloaded from the Firebase console, to the root of the Droid project and set its build action to GoogleServicesJson. For more information, see Add the Google Services JSON File.
-
Open the AndroidManifest.xml file and insert the following
<receiver>
elements into the<application>
element:<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>
-
Add a new class to the Droid project named
FirebaseRegistrationService
, and make sure that the followingusing
statements are present at the top of the file:using System.Threading.Tasks; using Android.App; using Android.Util; using Firebase.Iid; using Microsoft.WindowsAzure.MobileServices;
-
Replace the empty
FirebaseRegistrationService
class with the following code:[Service] [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })] public class FirebaseRegistrationService : FirebaseInstanceIdService { const string TAG = "FirebaseRegistrationService"; public override void OnTokenRefresh() { var refreshedToken = FirebaseInstanceId.Instance.Token; Log.Debug(TAG, "Refreshed token: " + refreshedToken); SendRegistrationTokenToAzureNotificationHub(refreshedToken); } void SendRegistrationTokenToAzureNotificationHub(string token) { // Update notification hub registration Task.Run(async () => { await AzureNotificationHubService.RegisterAsync(TodoItemManager.DefaultManager.CurrentClient.GetPush(), token); }); } }
The
FirebaseRegistrationService
class is responsible for generating security tokens that authorize the application to access FCM. TheOnTokenRefresh
method is invoked when the application receives a registration token from FCM. The method retrieves the token from theFirebaseInstanceId.Instance.Token
property, which is asynchronously updated by FCM. TheOnTokenRefresh
method is infrequently invoked, because the token is only updated when the application is installed or uninstalled, when the user deletes application data, when the application erases the Instance ID, or when the security of the token has been compromised. In addition, the FCM Instance ID service will request that the application refreshes its token periodically, typically every 6 months.The
OnTokenRefresh
method also invokes theSendRegistrationTokenToAzureNotificationHub
method, which is used to associate the user's registration token with the Azure Notification Hub.
-
Add a new class to the Droid project named
AzureNotificationHubService
, and make sure that the followingusing
statements are present at the top of the file:using System; using System.Threading.Tasks; using Android.Util; using Microsoft.WindowsAzure.MobileServices; using Newtonsoft.Json.Linq;
-
Replace the empty
AzureNotificationHubService
class with the following code:public class AzureNotificationHubService { const string TAG = "AzureNotificationHubService"; public static async Task RegisterAsync(Push push, string token) { try { const string templateBody = "{\"data\":{\"message\":\"$(messageParam)\"}}"; JObject templates = new JObject(); templates["genericMessage"] = new JObject { {"body", templateBody} }; await push.RegisterAsync(token, templates); Log.Info("Push Installation Id: ", push.InstallationId.ToString()); } catch (Exception ex) { Log.Error(TAG, "Could not register with Notification Hub: " + ex.Message); } } }
The
RegisterAsync
method creates a simple notification message template as JSON, and registers to receive template notifications from the notification hub, using the Firebase registration token. This ensures that any notifications sent from the Azure Notification Hub will target the device represented by the registration token.
-
Add a new class to the Droid project named
FirebaseNotificationService
, and make sure that the followingusing
statements are present at the top of the file:using Android.App; using Android.Content; using Android.Media; using Android.Support.V7.App; using Android.Util; using Firebase.Messaging;
-
Replace the empty
FirebaseNotificationService
class with the following code:[Service] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] public class FirebaseNotificationService : FirebaseMessagingService { const string TAG = "FirebaseNotificationService"; public override void OnMessageReceived(RemoteMessage message) { Log.Debug(TAG, "From: " + message.From); // Pull message body out of the template var messageBody = message.Data["message"]; if (string.IsNullOrWhiteSpace(messageBody)) return; Log.Debug(TAG, "Notification message body: " + messageBody); SendNotification(messageBody); } void SendNotification(string messageBody) { var intent = new Intent(this, typeof(MainActivity)); intent.AddFlags(ActivityFlags.ClearTop); var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot); var notificationBuilder = new NotificationCompat.Builder(this) .SetSmallIcon(Resource.Drawable.ic_stat_ic_notification) .SetContentTitle("New Todo Item") .SetContentText(messageBody) .SetContentIntent(pendingIntent) .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification)) .SetAutoCancel(true); var notificationManager = NotificationManager.FromContext(this); notificationManager.Notify(0, notificationBuilder.Build()); } }
The
OnMessageReceived
method, which is invoked when an application receives a notification from FCM, extracts the message content, and calls theSendNotification
method. This method converts the message content into a local notification that's launched while the application is running, with the notification appearing in the notification area.
Now, you are ready test push notifications in the app running on an Android device or the emulator.
The first two steps are required only when you're testing on an emulator.
- Make sure that you are deploying to or debugging on a device or emulator that is configured with Google Play Services. This can be verified by checking that the Play apps are installed on the device or emulator.
- Add a Google account to the Android device by clicking Apps > Settings > Add account. Then follow the prompts to add an existing Google account to the device, or to create a new one.
- In Visual Studio or Xamarin Studio, right-click the Droid project and click Set as startup project.
- Click Run to build the project and start the app on your Android device or emulator.
- In the app, type a task, and then click the plus (+) icon.
- Verify that a notification is received when an item is added.
This section is for running the Xamarin iOS project for iOS devices. You can skip this section if you are not working with iOS devices.
[!INCLUDE Enable Apple Push Notifications]
[!INCLUDE app-service-mobile-apns-configure-push]
Next, you will configure the iOS project setting in Xamarin Studio or Visual Studio.
[!INCLUDE app-service-mobile-xamarin-ios-configure-project]
-
In the iOS project, open AppDelegate.cs and add the following statement to the top of the code file.
using Newtonsoft.Json.Linq;
-
In the AppDelegate class, add an override for the RegisteredForRemoteNotifications event to register for notifications:
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { const string templateBodyAPNS = "{\"aps\":{\"alert\":\"$(messageParam)\"}}"; JObject templates = new JObject(); templates["genericMessage"] = new JObject { {"body", templateBodyAPNS} }; // Register for push with your mobile app Push push = TodoItemManager.DefaultManager.CurrentClient.GetPush(); push.RegisterAsync(deviceToken, templates); }
-
In AppDelegate, also add the following override for the DidReceiveRemoteNotification event handler:
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler) { NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary; string alert = string.Empty; if (aps.ContainsKey(new NSString("alert"))) alert = (aps[new NSString("alert")] as NSString).ToString(); //show alert if (!string.IsNullOrEmpty(alert)) { UIAlertView avAlert = new UIAlertView("Notification", alert, null, "OK", null); avAlert.Show(); } }
This method handles incoming notifications while the app is running.
-
In the AppDelegate class, add the following code to the FinishedLaunching method:
// Register for push notifications. var settings = UIUserNotificationSettings.GetSettingsForTypes( UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet()); UIApplication.SharedApplication.RegisterUserNotificationSettings(settings); UIApplication.SharedApplication.RegisterForRemoteNotifications();
This enables support for remote notifications and requests push registration.
Your app is now updated to support push notifications.
-
Right-click the iOS project, and click Set as StartUp Project.
-
Press the Run button or F5 in Visual Studio to build the project and start the app in an iOS device. Then click OK to accept push notifications.
[!NOTE] You must explicitly accept push notifications from your app. This request only occurs the first time that the app runs.
-
In the app, type a task, and then click the plus (+) icon.
-
Verify that a notification is received, and then click OK to dismiss the notification.
This section is for running the Xamarin.Forms WinApp and WinPhone81 projects for Windows devices. These steps also support Universal Windows Platform (UWP) projects. You can skip this section if you are not working with Windows devices.
[!INCLUDE app-service-mobile-register-wns]
[!INCLUDE app-service-mobile-configure-wns]
-
In Visual Studio, open App.xaml.cs in a Windows project, and add the following statements.
using Newtonsoft.Json.Linq; using Microsoft.WindowsAzure.MobileServices; using System.Threading.Tasks; using Windows.Networking.PushNotifications; using <your_TodoItemManager_portable_class_namespace>;
Replace
<your_TodoItemManager_portable_class_namespace>
with the namespace of your portable project that contains theTodoItemManager
class. -
In App.xaml.cs, add the following InitNotificationsAsync method:
private async Task InitNotificationsAsync() { var channel = await PushNotificationChannelManager .CreatePushNotificationChannelForApplicationAsync(); const string templateBodyWNS = "<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$(messageParam)</text></binding></visual></toast>"; JObject headers = new JObject(); headers["X-WNS-Type"] = "wns/toast"; JObject templates = new JObject(); templates["genericMessage"] = new JObject { {"body", templateBodyWNS}, {"headers", headers} // Needed for WNS. }; await TodoItemManager.DefaultManager.CurrentClient.GetPush() .RegisterAsync(channel.Uri, templates); }
This method gets the push notification channel, and registers a template to receive template notifications from your notification hub. A template notification that supports messageParam will be delivered to this client.
-
In App.xaml.cs, update the OnLaunched event handler method definition by adding the
async
modifier. Then add the following line of code at the end of the method:await InitNotificationsAsync();
This ensures that the push notification registration is created or refreshed every time the app is launched. It's important to do this to guarantee that the WNS push channel is always active.
-
In Solution Explorer for Visual Studio, open the Package.appxmanifest file, and set Toast Capable to Yes under Notifications.
-
Build the app and verify you have no errors. Your client app should now register for the template notifications from the Mobile Apps back end. Repeat this section for every Windows project in your solution.
- In Visual Studio, right-click a Windows project, and click Set as startup project.
- Press the Run button to build the project and start the app.
- In the app, type a name for a new todoitem, and then click the plus (+) icon to add it.
- Verify that a notification is received when the item is added.
You can learn more about push notifications:
- Sending Push Notifications from Azure Mobile Apps
- Firebase Cloud Messaging
- Remote Notifications with Firebase Cloud Messaging
- Diagnose push notification issues
There are various reasons why notifications may get dropped or do not end up on devices. This topic shows you how to analyze and figure out the root cause of push notification failures.
You can also continue on to one of the following tutorials:
- Add authentication to your app
Learn how to authenticate users of your app with an identity provider. - Enable offline sync for your app
Learn how to add offline support for your app by using a Mobile Apps back end. With offline sync, users can interact with a mobile app—viewing, adding, or modifying data—even when there is no network connection.