Firebase.Messaging messages not being received after update

Hello fellow Xamarin developers, thanks for dropping by i really need help on this
issue as it is driving me insane.

So to make a long story short me and my team has been working on this application with firebase
as our backend for about a year and a half now. Around a year ago we integrated Firebase FCM
into our system to send messages to our user's devices whenever they got notices in our database.

It worked fine until a couple of months ago when we were testing Android Oreo compability when we ran
into issues. This was of course the requirement of notification channels which we implemented and were able
to test and verify to be working on our handsets. However for the last 2 months we have had reports by testers
not receiving notices and i've been able to verify this issue by testing with them in person.

From what i can see from the logs of the cloud function that sends the notices is that they are sent correctly and most of the time the device tokens
are up to date and are registered correctly. I've added some event tracking to the app since then with app center and the strange thing is that it seems like the clients either receive the messages all the time, just some times or no times at all.

This is my MessagingService and InstanceIdService:

namespace Doshi.Droid
{
    [Service(Name = "com.doshi.droid.DoshiMessagingService", Enabled = true, Exported = true)]
    [IntentFilter(new[] {"com.google.firebase.MESSAGING_EVENT"})]
    public class DoshiMessagingService : FirebaseMessagingService
    {
        INoticePresenter _noticePresenter = new DoshiNoticePresenter();

        public override void OnMessageReceived(RemoteMessage message)
        {
            try
            {
                if(FirebaseAuth.Instance != null && FirebaseAuth.Instance.CurrentUser != null)
                {
                    Analytics.TrackEvent("FCM Received", new Dictionary<string, string>
                    {
                        {"UserID", FirebaseAuth.Instance.CurrentUser.Uid },
                        {"UserEmail", FirebaseAuth.Instance.CurrentUser.DisplayName },
                        {"Time", DateTime.Now.ToLongDateString() },
                        { "NoticeID", message.Data["notice_id"] }
                    });
                }
            }
            catch(Exception ex)
            {
                Crashes.TrackError(ex);
            }

            HandleNotice(message);
        }

        private void HandleNotice(RemoteMessage message)
        {
            int id = DateTime.Now.Millisecond;
            _noticePresenter.PresentNotice(this, message, id, Xamarin.Droid.Resource.Drawable.ic_logo, typeof(MainActivity));
        }
    }
}

InstanceIdClass - I upload the tokens to firebase here where i then retreive them from in my cloud function

namespace Doshi.Droid
{
    [Service(Name = "com.doshi.droid.DoshiInstanceIdService", Enabled =true,Exported =true)]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class DoshiInstanceIdService : FirebaseInstanceIdService
    {
        public override async void OnTokenRefresh()
        {
            base.OnTokenRefresh();

            var tokenService = new TokenService();
            await tokenService.UploadTokenAsync(FirebaseInstanceId.Instance.Token);
            Analytics.TrackEvent("New id issued");
        }
    }
}

I'm using the latest "stable" version of the firebase nugets. Someone on stackoverflow suggested to upgrade to the preview versions to get access
to the new way tokens are issued through the messaging service but i do not feel safe using preview nugets in production software and try to get around it
as often as possible.

I was also adviced to make sure the old GCM packages were uninstalled which i've made sure of as i recreated the project not long ago to move from pcl
to .net standard.

My AndroidManifest is pretty empty because i try to make use of Xamarins class attributes and let them inject during compilation.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="money.doshi.app" android:installLocation="preferExternal" android:versionName="1.0.2" android:versionCode="71">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
    <application android:label="Doshi">
        <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
        </provider>
        <uses-permission android:name="com.android.vending.BILLING" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <meta-data android:name="com.package.name" android:value="com.doshi.app" />
        <provider android:name="android.support.v4.content.FileProvider" android:grantUriPermissions="true" android:exported="false" android:authorities="com.doshi.app.provider">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
        </provider>
    </application>
</manifest>

What i found interesting was that my generated AndroidManifest(from obj output) contained many duplicate permissions that i believe is being injected
by the Xamarin.Firebase and Xamarin.GooglePlayServices packages:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="money.doshi.app" android:installLocation="preferExternal" android:versionName="1.0.2" android:versionCode="71">
  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-feature android:name="android.hardware.camera" android:required="false" />
  <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
  <application android:label="Doshi" android:largeHeap="true" android:name="md5c71614ee7424591206665a812156721a.MainApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher">
    <provider android:name="android.support.v4.content.FileProvider" android:authorities="money.doshi.app.fileprovider" android:exported="false" android:grantUriPermissions="true">
      <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
    </provider>
    <uses-permission android:name="com.android.vending.BILLING" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <meta-data android:name="com.package.name" android:value="com.doshi.app" />
    <provider android:name="android.support.v4.content.FileProvider" android:grantUriPermissions="true" android:exported="false" android:authorities="com.doshi.app.provider">
      <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
    </provider>
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_logo" />
    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/channel_id" />
    <activity android:configChanges="orientation|screenSize" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:launchMode="singleTask" android:name="money.doshi.app.MainActivity" android:screenOrientation="portrait" android:theme="@style/MainTheme">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="links.doshi.money" />
        <data android:scheme="https" />
      </intent-filter>
    </activity>
    <activity android:configChanges="orientation|screenSize" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:noHistory="true" android:theme="@style/SplashTheme" android:windowSoftInputMode="stateUnspecified|adjustPan" android:name="md5c71614ee7424591206665a812156721a.SplashActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <service android:enabled="true" android:exported="true" android:name="com.doshi.droid.DoshiInstanceIdService">
      <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
      </intent-filter>
    </service>
    <service android:enabled="true" android:exported="true" android:name="com.doshi.droid.DoshiMessagingService">
      <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
      </intent-filter>
    </service>
    <activity android:theme="@style/Theme.AppCompat.Translucent" android:name="md58df8abf514907713530ab2b6db8d7d9e.ReferActivity" />
    <activity android:name="naxm.socialauth.droid.GoogleSignInActivity" android:theme="@style/Theme.AppCompat.Translucent" />
    <receiver android:enabled="true" android:exported="false" android:label="Connectivity Plugin Broadcast Receiver" android:name="md59628c2715c1bb8febcc7ae8402df0582.ConnectivityChangeBroadcastReceiver" />
    <activity android:configChanges="orientation|screenSize" android:name="md54cd65ac53ae710bff80022afc423e0f3.MediaPickerActivity" />
    <receiver android:enabled="true" android:exported="false" android:name="md51558244f76c53b6aeda52c8a337f2c37.PowerSaveModeBroadcastReceiver" />
    <provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="money.doshi.app.mono.MonoRuntimeProvider.__mono_init__" />
    <provider android:authorities="money.doshi.app.firebaseinitprovider" android:name="com.google.firebase.provider.FirebaseInitProvider" android:exported="false" android:initOrder="100" />
    <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="money.doshi.app" />
      </intent-filter>
    </receiver>
    <!-- Internal (not exported) receiver used by the app to start its own exported services
             without risk of being spoofed. -->
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
    <!-- FirebaseInstanceIdService performs security checks at runtime,
             no need for explicit permissions despite exported="true" -->
    <service android:name="com.google.firebase.iid.FirebaseInstanceIdService" android:exported="true">
      <intent-filter android:priority="-500">
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
      </intent-filter>
    </service>
    <!-- FirebaseMessagingService performs security checks at runtime,
             no need for explicit permissions despite exported="true" -->
    <service android:name="com.google.firebase.messaging.FirebaseMessagingService" android:exported="true">
      <intent-filter android:priority="-500">
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
      </intent-filter>
    </service>
    <activity android:name="com.google.android.gms.appinvite.PreviewActivity" android:exported="true" android:theme="@style/Theme.AppInvite.Preview">
      <intent-filter>
        <action android:name="com.google.android.gms.appinvite.ACTION_PREVIEW" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </activity>
    <activity android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:excludeFromRecents="true" android:exported="false" />
    <!--Service handling Google Sign-In user revocation. For apps that do not integrate with
            Google Sign-In, this service will never be started.-->
    <service android:name="com.google.android.gms.auth.api.signin.RevocationBoundService" android:exported="true" android:permission="com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION" />
    <activity android:name="com.google.android.gms.common.api.GoogleApiActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:exported="false" />
    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
  </application>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
  <permission android:name="money.doshi.app.permission.C2D_MESSAGE" android:protectionLevel="signature" />
  <uses-permission android:name="money.doshi.app.permission.C2D_MESSAGE" />
</manifest>

If anyone of you have run into this problem, went through this process or has any idea of what is happening
then please let me know.

Thanks in advance.

Answers

  • jezhjezh Member, Xamarin Team Xamurai

    You can try to check the network status first.

    Besides, could you please provide us the phone brand and the api version of the phone that encounted this question?

Sign In or Register to comment.