Většina dnešních aplikací potřebuje přijímat vzdáleně odesílané notifikace - push notifikace. V tomto článku je ukázáno, jak docílit propojení AppCenter Push nofikací s Xamarin.Forms aplikací.

Následující článek se dělí na několik částí:

Při práci s AppCenter je nutno mít na paměti, že některé funkce jsou stále v přeběžném přístupu.

AppCenter - vytvoření aplikace

V první řadě je doporučené ve webovém portálu AppCenter vytvořit projekt (aplikaci), protože se jedná o nejjednodušší způsob, jak si zobrazit aktuální tutoriál pro integraci AppCenter do již existující aplikace.

AppCenterInit

Xamarin aplikace - nastavení aplikace

Po přidání projektu do AppCenter se zobrazí tutoriál, který se skládá z dvou kroků:

  • Přidání Nuget balíčku, pro tuto ukázku využejeme nuget balíčku: Microsoft.AppCenter.Push, který použijeme pro PushNotifikace
  • V aplikaci spuštění komunikace s AppCenter pomocí vygenerovaného klíče

AppCenterKey

Do nově vytvořené (nebo existující) Xamarin.Forms aplikace je třeba tento balíček naisntalovat do knihovny sdíleného kódu (.NET Standard) i do příslušných podprojektů (Android), tak jako je tomu na následujícím obrázku.

XamarinNuget

A do App.xaml.cs ve sdíleném projektu přidat:

1
2
3
4
using Microsoft.AppCenter.Push;
using Microsoft.AppCenter;

AppCenter.Start("2dea1c45-bb01-4dcf-9878-f11f7ddbf509", typeof(Push));

Výsledná třída App.xaml.cs může vypadat takto:

1
2
3
4
5
6
7
8
9
10
11
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            AppCenter.Start("2dea1c45-bb01-4dcf-9878-f11f7ddbf509", typeof(Push));
            MainPage = new MainPage();
        }
     ....
     }

Zaregistrování do Firebase

Nejprve je potřeba vytvořit projekt ve webovém portálu Firebase.

Po vytvoření projektu přidat aplikaci do Firebase, při zadávání musí jméno balíčku přesně odpovídat jménu balíčku Android aplikace, tak jako tomu je na následujícím obrázku:

FirebaseAppInit

Po vyplnění formuláře stáhnout google-services.json a vložit ho do Xamarin.Android aplikace. Po přidání je nutné nastavit akci sestavení jako GoogleServicesJson.

FirebaseAppInit

FirebaseAppInit

Pokud tato možnost není dostupná (bug), stačí restartovat Visual Studio Dalším krokem je editace AndroidManifest.xml, kam jsou vloženy řádky označené komentářem:

1
2
3
4
5
6
7
8
9
10
11
12
<application ...>
<!-- Přidat tyto řádky -->
    <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>
<!-- Toť vše :) -->
</application>

Posledním krokem je povolení AppCenter využívání služeb Firebase, tak že je do AppCenter přidán ServerKey z Firebase.

Ve FireBase je ServerKey k nalezení v Project Settings -> Cloud Messaging. V App Center je vložení Server Key posledním krokem v Push.

FirebaseAppInit

Handler pro příchozí zprávy

Zachycení zprávy je v aplikaci vyřešené pomocí handleru Push.PushNotificationReceived.

Do App.xaml.cs pod inicializaci AppCenter stačí přidat následující kód:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public App()
{
    InitializeComponent();

    AppCenter.Start("2dea1c45-bb01-4dcf-9878-f11f7ddbf509", typeof(Push));
    // Přidaný kód
    if (!AppCenter.Configured)
    {
        Push.PushNotificationReceived += (sender, e) =>
        {
            // Add the notification message and title to the message
            var summary = $"Push notification received:" +
                                $"\n\tNotification title: {e.Title}" +
                                $"\n\tMessage: {e.Message}";

            // If there is custom data associated with the notification,
            // print the entries
            if (e.CustomData != null)
            {
                summary += "\n\tCustom data:\n";
                foreach (var key in e.CustomData.Keys)
                {
                    summary += $"\t\t{key} : {e.CustomData[key]}\n";
                }
            }

            // Send the notification summary to debug output
            System.Diagnostics.Debug.WriteLine(summary);
        };
    }
}

V některých případech se stane, že zpráva dojde do zařízení, ale PushNotificationReceived se nezavolá. Pro tento případ je zde popsaný workaround, který tento problém řeší.

Wokraround: Zpráva není zpracována aplikací

Chyba je nejspíše na straně nuget balíčku AppCenter.Push. Naštěstí lze celou část kódu pro přijetí zprávy nativně reprodukovat.

K tomu je potřeba:

Vytvoření Android Service

V projektu pro Android vytvoříme třídu ForegroundFirebaseMessagingService, která dědí z FirebaseMessagingService, tedy využívá binding na nativní Firebase balíček (bez AppCenter).

Tato třída registruje IntentFilter pro firebase.MESSAGING_EVENT a obsahuje metodu, která je zavolaná po přijetí zprávy OnMessageReceived. V této metodě, kromě logů do konzole je i zaslání zprávy MessagingCentrem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using Firebase.Messaging;
... namespace
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class ForegroundFirebaseMessagingService : FirebaseMessagingService
{
    const string TAG = "MyFirebaseMsgService";
    public override void OnMessageReceived(RemoteMessage message)
    {
        Log.Debug(TAG, "From: " + message.From);
        Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
        MessagingCenter.Send<object, string>(this, "PushNotificationForegroundMessage", message.GetNotification().Body);
    }
}

MessagingCenter zasílající informaci z Android části projektu do Xamarin.Forms sdíleného kódu

Pro přijímání zpráv z MessagingCenter je nutné, aby ji měl kdo přijímat (zaregistrování k odběru). To můžeme provést v App.xaml.cs.

Pomocí arrow funkce je možné spustit svůj kód po obdržení zprávy, kód v ukázce zobrazuje Alert s obsahem z cloud notifikace.

1
2
3
4
5
6
7
MessagingCenter.Subscribe<object, string>(this, "PushNotificationForegroundMessage", (sender, args) => 
{
    Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
    {
        await DisplayAlert("PushNotificationForegroundMessage", args, "ok");
    });
});

Data, která jsou zasílána pomocí MessagingCenter je možné libovolně upravit. MessagingCenter není součástí AppCenter ani Firebase.