My notifications are not coming and I think my code may be correct

Asked

Viewed 595 times

1

I made several attempts to send Push Notification and none of them I was able to view in my App. I always thought until now, that I was wrong. But I followed two steps and saw that with the guys it was working and with me it wasn’t. So I started to think otherwise, that either the firebase wasn’t firing properly or my equipment, for hitherto unknown reasons, is not receiving. How did I come to this conclusion? Is that when I start the application, I break in several points and the moment I climb the app, on Onregistered the app for and there I get the token generated. Once I deregistered and registered and generated a new message and was with the previous token and not the new generated, then when I triggered the notification, gave error in firebase of :

Status of message: failed

I entered the valid token, gave the message of Envoy and in the App I can’t catch it. Something is blocking the receipt and I don’t know what it is. I’m suspicious of the Security Master, Vysor, My KNOX and etc or own Firebase, but I’m not sure. Look at the code I just made, which reported all above: Boot class

[Application]
    public class PushNotificationAppStater : Application
    {
        public static Context AppContext;

        public PushNotificationAppStater(IntPtr javaReference, JniHandleOwnership transfer) 
            : base(javaReference, transfer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            AppContext = this.ApplicationContext;

            //TODO: Initialize CrossPushNotification Plugin
            //TODO: Replace string parameter with your Android SENDER ID
            //TODO: Specify the listener class implementing IPushNotificationListener interface in the Initialize generic
            CrossPushNotification.Initialize<CrossPushNotificationListener>("806431458293");

            StartPushService();
        }

        public static void StartPushService()
        {
            AppContext.StartService(new Intent(AppContext, typeof(PushNotificationService)));

            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
            {

                PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(PushNotificationService)), 0);
                AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
                alarm.Cancel(pintent);
            }
        }

        public static void StopPushService()
        {
            AppContext.StopService(new Intent(AppContext, typeof(PushNotificationService)));
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
            {
                PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(PushNotificationService)), 0);
                AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
                alarm.Cancel(pintent);
            }
        }
    }

Message and status system class

public class CrossPushNotificationListener : IPushNotificationListener
    {
        public void OnError(string message, DeviceType deviceType)
        {

        }

        public void OnMessage(JObject values, DeviceType deviceType)
        {

        }

        public void OnRegistered(string token, DeviceType deviceType)
        {

        }

        public void OnUnregistered(DeviceType deviceType)
        {

        }

        public bool ShouldShowNotification()
        {
            return true;
        }
    }

Mainactivity

[Activity(Label = "App1", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }

My App.xaml.Cs public partial class App : Application { public App() { Initializalizecomponent();

    MainPage = new App1.MainPage();
}

protected override void OnStart()
{
    CrossPushNotification.Current.Unregister();
    CrossPushNotification.Current.Register();
}

protected override void OnSleep()
{
    // Handle when your app sleeps
}

protected override void OnResume()
{
    // Handle when your app resumes
}

}

My android.manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.global.app.br" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="15" />
    <application android:label="App1.Android" android:icon="@drawable/icon">
    <service
        android:name=".Messaging.FirebaseIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
  </application>
</manifest>

The rest has the google-services.json with build option for google-services.json and the installed package is: Xam.Plugin.Pushnotification Newtonsoft.json

These were the only plugins installed by me. What might be this problem?

  • Did you test receive the notification with the app in background ???

  • @pnet where are the receivers declared in the manifest? Where are the firebase receivers and services classes??? Remove everything from your project and follow exactly what is written in this guide of Xamarin’s documentation. I did it for him and it worked right. But here he makes the type of basic notification, then has to see to implement his own notification.

  • @Grupocdsinformática, I tried to do for this example, but I was giving the go when trying to install this reference: Xamarin.Google.Play.Services.Base, said it was not possible to install in a Mono project.Droid I think, I even have a post answered by LINQ. I use Xamarin.Forms, but I’ll do another project from scratch with this example. You or Colleta told me if I had installed google-services or something like that on my phone, I don’t know if it is, but I open a lot of stuff from google, like gmail, Chrome and so on. It has to do with this?

  • @Grupocdsinformática, when I try to catch the token I have this error: Java.lang.Illegalstateexception: Default Firebasepp is not initialized in this process com.inet.Droid.br. Make sure to call Firebasepp.initializeApp(Context) first. occurred. It says that firebaseApp was not initialized. How do you do it? I was doing it as an example. The error is in this line: Log.Debug(TAG, "Instanceid token: " + Firebaseinstanceid.Instance.Token);

  • I saw that in the properties of google-services.json in Build Action I do not have the option Googleservicesjson

  • Firebasepp.initializeApp(Context) you have to do in Application (speaking of Android blz), and Googleservices.json is not compiled at all. But at least in the android Apps, it will imbutido.

  • Let’s move the conversation to the chat, I’ll help you solve the problem.

Show 2 more comments

1 answer

3


NOTE: STEP BY STEP FOR CONFIGURATION IN XAMARIN FORMS, THINKING ABOUT ANDROID SETTINGS. FOR IOS, I CAN DO A STEP BY STEP LATER.

Come on, I’ll shape the answer to the topic. The whole process is simple, but it gets hard to understand because a lot of the documentation is "make it work".

So come on.

Preparing the project.

First thing you need to do is update the SDK and set it up in the project Properties to point to the correct API. I will show in my project (Xamarin.Forms) how it is, in the images below. Important: Add internet permission to the application.

android.manifest

Application

Once this is done, we need to update the nuget files. The secret here, is to build the project after changing the settings above, close Visual Studio and open again, so it can detect the changes (the old get out of the VW Bug and enter the VW Bug).

Update everything that appears, and then we will add two references: Xamarin.GooglePlayServices.Base and Xamarin.Firebase.Messaging. Others are added automatically, such as dependencies.

nuget

Once that’s done, let’s go for the code.

Implementation of codes.

I’ll assume you’ve already created a project in Firebase, added the application in it. If you haven’t, you can see the step by step here.

First thing we have to get right, the project manifest. I’ll put my manifest here

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="br.com.grupoestudos.app1xamarin" android:versionCode="1" android:versionName="1">
    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="25" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:label="App1.Android" android:icon="@drawable/Icon">

    <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>

Explaining what happens underneath the scenes. Xamarin will register two Intentreceivers to be able to listen to firebase events. Because firebase sends messages to Google Play Services, it replicates the message to the apps. In this case, only the current application will receive a message sent by firebase, to the applicationId. This value does not need to change as it automatically picks up the google-services.json file.

Speaking of the file, the second step is to take the file google-services.json that is downloaded after setting up the app in Firebase, and put in the root of the android project. Then open the application properties and switch Build Action to Googleservicesjson. This option will only appear (if it doesn’t appear on press), after installing Xamarin.Firebase.Messaging and closing and opening Visual Studio again (it’s horribly annoying to have to do this, and I don’t even know why you need to do it).

google-services.json properties

Third. Let’s create a class, which implements Firebaseinstanceidservice. The app will call this class alone, so you can register the app in the Firebase project. It does this automatically by reading and registering the app underneath the scenes.

using Android.App;
using Android.Content;
using Firebase.Iid;
using Android.Util;
using Firebase.Messaging;

namespace App1.Droid.Firebase
{
    [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);
            SendRegistrationToServer(refreshedToken);
        }
        void SendRegistrationToServer(string token)
        {
            //Neste método, é possível enviar o token para um servidor ou api, atualizando o token do dispositivo.
        }
    }
}

Once this is done, we can run the app and it will already be working for background messages (when the app is minimized) only!!!!!!

If an error occurs when running, saying that you have to call Firebasepp.initializeApp(Context);, do not despair. Give a clean on Solution and build again, that the error goes away.

Messages in foreground (when it is open)

For this to work, we will need to create one more class, which implements Firebasemessagingservice. This class will pick up the message coming from Firebase, and will show an android notification.

using Android.App;
using Android.Content;
using Firebase.Messaging;
using Android.Util;

namespace App1.Droid.Firebase
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : 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);

            SendNotification(message.GetNotification().Body);
        }

        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 Notification.Builder(this)
                .SetSmallIcon(Resource.Drawable.Icon)
                .SetContentTitle("FCM Message")
                .SetContentText(messageBody)
                .SetAutoCancel(true)
                .SetContentIntent(pendingIntent);

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

Extra

The firebase message sent, she either sends it to the app, or sends it to some device. In order not to have to read the tokens and then run after sending a message for each token, there are the Topics.

You can subscribe to a topic, and then push it to that topic, and all the devices subscribed to it will receive it. Below is the code of my Mainactivity showing the inscription of the topic. One thing, the topics take a while to appear on the firebase console, so create all the topics you need and sign up on them.

using System;

using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

using Android.Gms.Common;
using Android.Util;
using Firebase.Iid;
using Firebase.Messaging;

namespace App1.Droid
{
    [Activity (Label = "App1", Icon = "@drawable/icon", Theme="@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        const string TAG = "MainActivity";

        protected override void OnCreate (Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar; 

            base.OnCreate (bundle);

            global::Xamarin.Forms.Forms.Init (this, bundle);
            LoadApplication (new App1.App ());

            Log.Debug(TAG, "InstanceID token: " + FirebaseInstanceId.Instance.Token);

            //Aqui eu me inscrevo no tópico.
            FirebaseMessaging.Instance.SubscribeToTopic("news");
        }
    }
}
  • Very good. I already have a project now working as we talked, I will implement it in another. It is good for studies. Googleplayservice.Base not that install on my Xam.Forms, but I install on an android project only, but I will try again. Anyway, I know the site doesn’t like it, but thank you!!!

  • Dude, I can’t get the token. I put a break, the first time it stopped, but now it does not stop and when I send with the previous token gives unregistered token error, meaning that the token has changed. With each build it changes, but this is normal. I will try to send to the service and send message per console I made.

  • Uses the Sendregistrationtoserver(string token) method to send the new token to your server when it is generated. Now, push has a business when it generates in debug tbm that has hr catching, time that does not. In release works perfect. If it is the case (as with me), turn off the wifi and on, or restart the device/ emulator.

  • Dude, I’m not getting the token in the Sendregistrationtoserver method and getting caught in Mainactivity Firebaseinstanceid.Instance.Token the message I pick up when I send a notification is: Not Registered. The Server Key is correct as I get there in Cloud Messaging project, but the token may not be this or it is? So why the message?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.