Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FCM (FirebaseMessagingService) OnNewToken not being hit with Android

I'm following the instructions on this page to create the push notifications. I've actually done it once before and was able to get it to work (a few weeks back), took some time away, and figured I'd do the tutorial again as a refresher only now, for some reason, I can't even get the code to hit the OnNewToken method to generate my token and register the device with the notification hub.

I've watched dozens of videos, read other tutorials, and they're all saying / showing pretty much the same thing so I think I need a new pair of eyes to show me what I'm missing this 2nd time around.

I've tried to pull out specific information but still keep it as readable as I could.

Installed NuGet packages:

  1. Xamarin.Firebase.Messaging - v71.1740.0
  2. Xamarin.GooglePlayServices.Base - v71.1610.0
  3. Xamarin.Forms - v4.4.0.991640

Files in Android project
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="(my firebase package / project package name)" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<!--
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
-->
<application>
    <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>
</application>
</manifest>

AppConstants

public static class AppConstants
{
    public static string NotificationChannelName { get; set; } = "XamarinNotifyChannel";
    public static string NotificationHubName { get; set; } = "(my azure notification hub name)";
    public static string ListenConnectionString { get; set; } = "(my default listen shared access signature from azure portal)";
    public static string DebugTag { get; set; } = "XamarinNotify";
    public static string[] SubscriptionTags { get; set; } = { "default" };
    public static string FCMTemplateBody { get; set; } = "{\"data\":{\"message\":\"$(messageParam)\"}}";
    public static string APNTemplateBody { get; set; } = "{\"aps\":{\"alert\":\"$(messageParam)\"}}";
}

FirebaseService

[Service(Name = "(my package name).MyFirebaseMessagingService")]
[IntentFilter(new[] {  "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseService : FirebaseMessagingService
{
    public override void OnNewToken(string token)
    {
        base.OnNewToken(token);
        Console.WriteLine("NEW_TOKEN", token);
        SendRegistrationToServer(token);
    }

    void SendRegistrationToServer(string token)
    {
        NotificationHub hub = new NotificationHub(AppConstants.NotificationHubName, AppConstants.ListenConnectionString, this);
        // register device with Azure Notification Hub using the token from FCM
        Registration reg = hub.Register(token, AppConstants.SubscriptionTags);
        // subscribe to the SubscriptionTags list with a simple template.
        string pnsHandle = reg.PNSHandle;
        hub.RegisterTemplate(pnsHandle, "defaultTemplate", AppConstants.FCMTemplateBody, AppConstants.SubscriptionTags);
    }

    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        string messageBody = string.Empty;
        if (message.GetNotification() != null)
        {
            messageBody = message.GetNotification().Body;
        }
        else
        {
            messageBody = message.Data.Values.First();
        }
        try
        {
            MessagingCenter.Send(messageBody, "Update");
        }
        catch (Exception e)
        { }
        SendLocalNotification(messageBody);
    }

    void SendLocalNotification(string body)
    {
        var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.ClearTop);
        intent.PutExtra("message", body);

        //Unique request code to avoid PendingIntent collision.
        var requestCode = new Random().Next();
        var pendingIntent = PendingIntent.GetActivity(this, requestCode, intent, PendingIntentFlags.OneShot);

        var notificationBuilder = new NotificationCompat.Builder(this)
            .SetContentTitle("XamarinNotify Message")
            .SetSmallIcon(Resource.Drawable.ic_launcher)
            .SetContentText(body)
            .SetAutoCancel(true)
            .SetShowWhen(false)
            .SetContentIntent(pendingIntent);

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
        }

        var notificationManager = NotificationManager.FromContext(this);
        notificationManager.Notify(0, notificationBuilder.Build());
    }
}

google-services.json
I just downloaded this file from Firebase, added it to the Android project and set the Build Action to GoogleServicesJson.

Hopefully somebody can see what I'm missing as I've had this same tutorial working before.

like image 418
user1818298 Avatar asked Dec 22 '22 19:12

user1818298


2 Answers

Please uninstall the application in your android, then redeploy it.

onNewToken() will be called only once per installation.

If you need it to be called again, uninstall the app from your device and restart it.

like image 149
Leon Lu - MSFT Avatar answered May 13 '23 06:05

Leon Lu - MSFT


You forgot [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]

[Service()]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class FirebaseService : FirebaseMessagingService
    {
like image 42
JeePakaJP Avatar answered May 13 '23 06:05

JeePakaJP