InstanceID API 返回的 GCM 令牌给出 NotRegistered 错误
Posted
技术标签:
【中文标题】InstanceID API 返回的 GCM 令牌给出 NotRegistered 错误【英文标题】:GCM Token returned by InstanceID API gives NotRegistered error 【发布时间】:2016-04-02 15:15:24 【问题描述】:我在我的应用程序中使用 GCM 并使用 InstanceId
API 生成 GCM 令牌。我正面临InstanceId
API 返回的令牌无效的问题。
我使用 Postman 来检查令牌,并且不时地在某些设备中尝试使用令牌会引发 NotRegistered 错误。虽然,如果我随后强制执行GCMInstanceIdListener
服务,它会再次调用GCMRegistrationService
,这一次我得到了正确的令牌。
有没有办法检查我在GCMRegistrationService
中收到的令牌是否有效?我知道我们可以调用 https://android.googleapis.com/gcm/send
并验证令牌,但它需要在标头中传递服务器密钥,我不想将其存储在客户端上。
这就是我的代码的样子:
public class GCMInstanceIdListener extends InstanceIDListenerService
@Override
public void onTokenRefresh()
Intent intent = new Intent(this, GCMRegistrationService.class);
startService(intent);
public class GCMRegistrationService extends IntentService
private static final String TAG = "GCMRegistrationService";
public GCMRegistrationService()
super(TAG);
@Override
protected void onHandleIntent(Intent intent)
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(BuildConfig.GCM_SENDER_ID,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.d(TAG, "GCM Token : " + token);
【问题讨论】:
【参考方案1】:每次启动应用时运行GCMRegistrationService
,并检查您在客户端本地保存的令牌是否与收到的令牌匹配。
@Override
protected void onHandleIntent(Intent intent)
String token = InstanceID.getInstance(this).getToken(BuildConfig.GCM_SENDER_ID,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String savedToken = prefs.getString("token", "");
if(!token.equals(savedToken))
prefs.edit().putString("token", token).apply();
sendTokenToBackend(token); // If needed
编辑:另外,请确保您拥有 GET_ACCOUNTS 权限。最近,我从我的应用程序中删除了此权限,并且我的设备上出现了 NotRegistered 错误。如果您的应用针对 API 23+,您需要在运行时请求此权限。
【讨论】:
我可以这样做,但在我们的用例中,我们需要在用户第一次打开应用程序时立即向他们发送推送消息。运行GCMRegistrationService
只会从第二次开始有帮助。即使在全新安装中,当第一次调用 GCMRegistrationService
时,我也会得到一个无效的令牌。
你为什么不关注谷歌的示例 gcm 客户端。它使用本地广播来通知活动注册已完成。然后,您可以继续执行其余的逻辑。至于无效令牌,我能想到的唯一两件事是您的 google-services.json 有问题(可能是文件损坏)或者您没有 GET_ACCOUNTS 权限(可能是 Android 6.0+ 权限问题)
嗯,我会检查的。虽然我们的清单中确实有 GET_ACCOUNTS
权限,并且我已经重新复制了几次 json 文件,但它并没有解决问题。
GET_ACCOUNTS 被定义为“正常”权限,但显然需要在 API 23+ 的运行时请求,就好像它是“危险”权限一样。至少这是在我的应用中发生的情况。
是的,但我们目前在我们的应用程序中没有针对 API 23+。以上是关于InstanceID API 返回的 GCM 令牌给出 NotRegistered 错误的主要内容,如果未能解决你的问题,请参考以下文章
Android GCM InstanceId.getToken() -> java.io.IOException: TIMEOUT
为啥 InstanceID 总是返回一个令牌,尽管有错误的 senderId?