发送一条通知后出现未注册令牌错误

16
我在使用Firebase时遇到了一个问题: 1. 我的应用在首次启动时接收到了令牌。 2. 我可以从Firebase控制台向注册的令牌发送通知。 3. 如果我在第2步后尝试使用控制台再次发送通知,则会在第二次尝试后显示“未注册的令牌”。
我的清单中已经有了所有必要的配置,并且google service.json文件也已经放置在正确的位置并进行了正确的配置。我相信一切都是正确的,因为该应用可以接收一次通知,问题只有在此之后才开始出现。
更新1: 如果卸载应用程序并重新安装它,则我也只能收到一次通知。
想查看代码的人,请看我如何获取令牌:
@Override
public void onTokenRefresh() {

    //Getting registration token
     refreshedToken = FirebaseInstanceId.getInstance().getToken();

    //Displaying token on logcat
    Log.d(TAG, "Refreshed token: " + refreshedToken);
     saveDeviceToken(refreshedToken);
}

这个函数只在第一次启动时被调用,之后我没有看到它被调用过(我认为这是预期的行为)。

OnMessage received也会在第一次通知时被调用,然后它就再也不会被调用了:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d("FCM", "From: " + remoteMessage.getFrom());

    if (remoteMessage.getNotification() != null) {
        Log.d("FCM", "Notification Message Body: " + remoteMessage.getNotification().getBody());
        sendNotification(remoteMessage.getNotification().getBody());
    }
}

更新2: 尝试使用相同的服务器密钥和令牌命中 FCM 的 HTTP API,得到以下响应:

   {
  "multicast_id": 6286279702096230688,
  "success": 0,
  "failure": 1,
  "canonical_ids": 0,
  "results": [
    {
      "error": "NotRegistered"
    }
  ]
}

为了避免混淆,这里提供更多细节:

  • Android Studio版本:v2.3.1
  • Google Play服务版本:10.0.1
  • 包含的库:核心,数据库,存储,消息 - 所有的版本都与Google Play服务10.0.1相同

更新3:Firebase崩溃,数据库和存储在同一个项目中工作(这表明google-service.json文件是正确的)。

请帮助我解决这个问题。


在测试时,您是否尝试先卸载并重新安装应用程序? - AL.
1
是的!我尝试过这个。我还尝试了重建缓存、完全更改包和json文件。 - Irfan Raza
我建议您将Google Play服务和Firebase更新到最新的10.2.4版本。Firebase仍处于后期测试阶段,其中许多功能会在更新中出现故障并得到修复。例如,从Firebase 10.0.x到10.2.x,更改用户名/照片时存在错误,并且没有实时显示,需要重新登录。在多次联系Firebase之后,这个问题已经得到了解决。此外,当您的应用程序在后台运行时,将调用onMessageReceived()。如果您的应用程序停止,则通知将由默认系统通知处理。 - Nihal
4个回答

1
我记得以前也遇到过类似的问题。以下是我的解决方法,目前运行良好。希望可以帮到你。
PreferenceStore是一个辅助类,用于保存、编辑和删除共享偏好设置。
@Override
public void onTokenRefresh() {
    String token = FirebaseInstanceId.getInstance().getToken();
    Log.i(TAG, "New FCM Token: " + token);

    setup_flag = PreferenceStore.getBoolean(getApplicationContext(), PrefKeys.IS_FIRST_FCM_TOKEN);
    if (!setup_flag) {
        // save token and boolean value in shared preferences for 
        // the first time you run the app after install
        PreferenceStore.saveString(getApplicationContext(), "FCM_TOKEN", token);
        PreferenceStore.saveBoolean(getApplicationContext(), "IS_FIRST_FCM_TOKEN", true);
    } else {
        // other time your app loads, update the token (like call the API endpoint).
    }
}

0

当以下情况发生时,注册令牌可能会更改:

  • 应用程序删除实例ID
  • 应用程序在新设备上恢复
  • 用户卸载/重新安装应用程序
  • 用户清除应用程序数据。

您可以在此处查看文档here

您还可以阅读关于 FCM 错误的信息here 这仅适用于调试模式,因此您可以在启动器活动中调用此方法,这将接受测试/开发服务器的 HTTPS 证书,因为 HTTPS 证书无效/不受信任 发布后不会出现此问题。

private void RegisterFireBase()
        {

if (BuildConfig.DEBUG) {    
            Task.Run(() =>
            {
                var instanceId = FirebaseInstanceId.Instance;
                instanceId.DeleteInstanceId();
                Android.Util.Log.Debug("TAG", "{0} {1}", instanceId?.Token?.ToString(), instanceId.GetToken(GetString(Resource.String.gcm_defaultSenderId), Firebase.Messaging.FirebaseMessaging.InstanceIdScope));

            });


            ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;



        }

这个答案是错误的,没有解决问题。 - Ehsan Bayat

0

FCM 是 GCM 的相反。

在使用 GCM 类时,TokenID 会不时地刷新,因此它也会在服务器上的数据库中更新。

在使用 FCM 时,FCM 的基本架构是基于唯一的 TokenID 运作的,这就是 onTokenRefresh 只调用一次的原因。

你所需要做的就是保存你最初生成的 TokenID 并相应地利用它。

P.S:在 FCM 中,TokenID 不会刷新,除非应用程序被重新安装。


只是想告诉您,我正在将令牌ID保存在我的数据库中,当我发送通知时,第一条通知可以正常工作,但在所有后续通知中,它会显示上述错误。 - Irfan Raza
这与缓存或存储令牌无关,而是与注销令牌有关。当 FCM 注销您的令牌时,无论您是否保存它都没有关系。 - Ehsan Bayat

-2

这是我解决问题的方法。

正如大家所指出的,.json文件的包名可能是此故障的主要原因,这在这里也是正确的,但有一个小插曲。

我从Firebase下载了.json文件,并假设正确的.json文件已被下载。不幸的是,由于Firebase中的某些错误,在下载文件时,我总是得到其他项目(Firebase应用程序)的.json文件。通过研究下载的文件,我找到了问题所在,并手动更改了.json文件中的包名和密钥。

我建议大家在尝试其他任何操作之前检查所包含的.json文件,因为这是此类问题的主要原因。


如果您收到的第一条通知不是关于软件包名称的,则您的答案也是错误的。 - Ehsan Bayat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接