FCM - 重新调试应用程序后发送消息时 Android Xamarin NotRegistered 错误 [英] FCM - Android Xamarin NotRegistered error when sending message after re-debugging the App

查看:15
本文介绍了FCM - 重新调试应用程序后发送消息时 Android Xamarin NotRegistered 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Xamarin Android 中开发应用程序,对于通知,我使用 FCM 预发布包:https://www.nuget.org/packages/Xamarin.Firebase.Messaging/

I am developing an App in Xamarin Android, for notifications I am using FCM the Pre-Release package: https://www.nuget.org/packages/Xamarin.Firebase.Messaging/

现在,如果我清理应用程序数据,一切正常,OnTokenRefresh 事件被触发并生成一个新令牌 - 当我在此令牌上发送新通知时,通知由OnMessageReceived() 中的设备 -

Now everything works fine if I clean the App data, the OnTokenRefresh event is fired and a new token is generated - when I send a new notification on this Token the notification is sent and received by the device in OnMessageReceived() -

问题是当我更改代码并再次运行应用程序时,如果我使用旧令牌,我会在发送通知时收到 NotRegistered 错误,但是如果我去清理应用程序数据,然后触发 OnTokenRefresh() 生成新令牌 - 新令牌有效.

The problem is when I make changes to the code and run the application again, if I use the old token I get the NotRegistered Error when sending a notification, but if I go and clean the App Data, then the OnTokenRefresh() is fired a new token is generated - the new token works.

这里有类似的问题,但这是 GCM(我正在使用 FCM):

Similar issue here, but this is GCM (I am using FCM):

谷歌云消息不"注册失败并取消订阅最佳做法?

https://stackoverflow.com/a/36856867/1910735

https://forums.xamarin.com/discussion/65205/google-cloud-messaging-issues#latest

我的FCMInstanceIdService

[Service, IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class FCMInstanceIdService : FirebaseInstanceIdService
{
    private string Tag = "FCMInstanceIdService";

    public override void OnTokenRefresh()
    {
        var fcmDeviceId = FirebaseInstanceId.Instance.Token;

        if (Settings.DeviceId != fcmDeviceId)
        {
            var oldDeviceId = Settings.DeviceId;

            Settings.DeviceId = fcmDeviceId;

            //TODO: update token on DB - Currently OnTokenRefresh is only called when: 1. App data is cleaned, 2. The app is re-installed
            //_usersProvider.UpdateUserDeviceId(oldDeviceId, fcmDeviceId);
        }

        base.OnTokenRefresh();
    }
}

我的消息接收服务:

[Service, IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FCMListenerService : FirebaseMessagingService
{
    private string Tag = "FCM_Listener_Service";

    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);

        var notification = message.GetNotification();
        var data = message.Data;
        var title = notification.Title;
        var body = notification.Body;

        SendNotification(title, body);
    }

    private void SendNotification(string title, string body)
    {
        //TODO: Display notification to user
    }
}

清单:

<application android:label="TBApp" android:theme="@style/TBAppTheme">

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

如何在 DEBUG 模式下强制刷新 FCM Token,以免每次运行应用程序时都删除应用程序数据?

How do I force refresh the FCM Token in DEBUG mode so I don't have to delete the App Data every time I run the application?

推荐答案

由于此问题仅在调试应用程序时从 Visual Studio 运行应用程序时发生(不在部署到 PlayStore 的版本中),因此我采取了哪些措施来解决该问题暂时是我创建了以下服务:

As this issue only happens when running the Application from Visual Studio while debugging the application (not in the version deployed to PlayStore), what I did to solve the issue temporarily is I created the following service:

    [Service]
    public class FCMRegistrationService : IntentService
    {
        private const string Tag = "FCMRegistrationService";
        static object locker = new object();

        protected override void OnHandleIntent(Intent intent)
        {
            try
            {
                lock (locker)
                {
                    var instanceId = FirebaseInstanceId.Instance;
                    var token = instanceId.Token;

                    if (string.IsNullOrEmpty(token))
                        return;

#if DEBUG
                    instanceId.DeleteToken(token, "");
                    instanceId.DeleteInstanceId();

#endif


                }
            }
            catch (Exception e)
            {
                Log.Debug(Tag, e.Message);
            }
        }
    }

然后在我的启动活动(每当应用程序打开时加载的活动执行以下操作:

then in my launch Activity (the activity that loads whenever the Application is opened is do the following:

protected override void OnCreate(Bundle savedInstanceState)
{
            base.OnCreate(savedInstanceState);


#if DEBUG
            if (!IsMyServiceRunning("FCMRegistrationService"))
            {
                var intent = new Intent(this, typeof(FCMRegistrationService));
                StartService(intent);
            }

            // For debug mode only - will accept the HTTPS certificate of Test/Dev server, as the HTTPS certificate is invalid /not trusted
            ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;
#endif

}

这将注销您现有的 FCMToken 并刷新 Token,因此将调用 OnTokenRefresh 方法,然后您必须编写一些逻辑来更新服务器上的 FCMToken.

This will unregister your existing FCMToken and will refresh the Token, so the OnTokenRefresh method will be called, then you will have to write some logic to update the FCMToken on the server.

[Service, IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class FCMInstanceIdService : FirebaseInstanceIdService
{
   // private string LogTag = "FCMInstanceIdService";

    public override void OnTokenRefresh()
    {
        var fcmDeviceId = FirebaseInstanceId.Instance.Token;

        // Settings (is Shared Preferences) - I save the FCMToken Id in shared preferences 
       // if FCMTokenId is not the same as old Token then update on the server

        if (Settings.FcmTokenId != fcmDeviceId)
        {
            var oldFcmId = Settings.FcmTokenId;

            var validationContainer = new ValidationContainer();

            // HERE UPDATE THE TOKEN ON THE SERVER
            TBApp.Current._usersProvider.UpdateFcmTokenOnServer(oldFcmId, fcmDeviceId, validationContainer);

            Settings.FcmTokenId = fcmDeviceId;

        }

        base.OnTokenRefresh();
    }
}

这篇关于FCM - 重新调试应用程序后发送消息时 Android Xamarin NotRegistered 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆