Firebase的onTokenRefresh()方法未被调用

73
在我的MainActivity中,通过使用FirebaseInstanceId.getInstance().getToken()命令,我可以看到标记并且它会显示生成的标记。但是,在我的MyFirebaseInstanceIDService中,该类扩展了FirebaseInstanceIdServiceonTokenRefresh()没有被调用,尽管在这个函数中说最初生成了标记。我需要调用sendRegistrationToServer(),所以我想知道为什么它不进入 onTokenRefresh()函数。
这是我的代码:
public class MyFirebaseInstanceIDService  extends FirebaseInstanceIdService {


@Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);

        sendRegistrationToServer(refreshedToken);
    }
}

可能是Firebase FCM force onTokenRefresh() to be called的重复问题。 - Machado
2
请完整阅读问题。这个问题不是你提到的那一个重复的问题。@Machado - Wijay Sharma
13个回答

106

只有在生成新令牌时,FirebaseInstanceIdService中的onTokenRefresh才会被调用。如果您的应用程序之前已安装并生成了令牌,则不会调用onTokenRefresh。尝试卸载和重新安装该应用程序以强制生成新令牌,这将导致调用onTokenRefresh。

还要确保您的FirebaseInstanceIdService在AndroidManifest.xml文件中正确定义。

请在Manifest文件中进行配置。

 <service
        android:name="com.bnt.etailers.fcm.MyFireBaseInstanceIDService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

    <service
        android:name="com.bnt.etailers.fcm.GCMNotificationIntentService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

FirebaseInstanceIdService类

public class MyFireBaseInstanceIDService extends FirebaseInstanceIdService {


private static final String TAG = MyFireBaseInstanceIDService.class.getSimpleName();

@Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    if (refreshedToken!=null) {
        SettingPreferences.setStringValueInPref(this, SettingPreferences.REG_ID, refreshedToken);
    }
    // TODO: Implement this method to send any registration to your app's servers.
    sendRegistrationToServer(refreshedToken);
}
// [END refresh_token]

/**
 * Persist token to third-party servers.
 *
 * Modify this method to associate the user's FCM InstanceID token with any server-side account
 * maintained by your application.
 *
 * @param token The new token.
 */
private void sendRegistrationToServer(String token) {
    // Add custom implementation, as needed.
}}
FirebaseMessagingService类。
public class GCMNotificationIntentService extends FirebaseMessagingService {
// Sets an ID for the notification, so it can be updated


public GCMNotificationIntentService() {
    super();
}


@Override
public void onMessageReceived(RemoteMessage message) {

}}

1
文档看起来有些混乱(https://firebase.google.com/docs/cloud-messaging/android/client),它说当应用程序删除实例ID时,注册令牌可能会更改,如果我手动调用FirebaseInstanceId.getInstance().deleteInstanceId(); 我期望会生成一个新的令牌,但实际上在这种情况下什么也没有发生,onTokenRefresh从未被调用。 - WenChao
2
为什么要将令牌保存到共享首选项中 - 如果您可以随时调用FirebaseInstanceId.getInstance().getToken()来获取其值? - Alexander Farber
@WenChao 请确保通过 InstanceID.getInstance(this).deleteInstanceID() 调用 PlayService 的 InstanceID,并在后台线程中调用它。成功删除后,请调用 InstanceID.getInstance(this).getID() 生成新的令牌。 - Salis
@Alexander Farber,这是因为您只能获取一次令牌,您需要将其持久化以便以后使用。例如,我正在开发一个应用程序,不需要用户注册,但如果他想订阅某些更新,则可以注册,我可以发送他设备的令牌和他的数据,但如果我在他第一次安装应用程序时就获得了令牌,那将不可能实现。 - Sterling Diaz
我正在KitKat及以上设备上测试它,在KitKatonTokenRefresh方法没有触发FCM版本11.6.2 - Sagar

23

我和你遇到了相同的问题。我的错误是:我把 <service> 标签放在了 AndroidManifest.xml 文件中 <application> 标签的外面。

现在我的文件看起来像这样:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <service
        android:name=".MyFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

    <service
        android:name=".MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
</application>

它能够正常运行,没有任何问题。


1
感谢这个帖子:https://dev59.com/1VoU5IYBdhLWcg3wi3WW - viplezer
很好的答案...这是返回的Facebook ID吗?因为我正在尝试这样做,但我得到了一个非常大的令牌。 - Juan
Facebook?Firebase?在FirebaseInstanceIDService子类的onTokenRefresh方法中获取Firebase Cloud Messaging的令牌,是一个长字符串,我的令牌有152个字符。 - viplezer
这对我来说是解决方案。 - jet_choong
@viplezer 在我的 KITKAT 上无法获取 token,请帮忙。 - Sagar

17

是的,这有时可能会发生。

请在您想要获取您的 FCM ID 的任何位置调用以下方法。

    try {
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
            Log.d("Firbase id login", "Refreshed token: " + refreshedToken);
        } catch (Exception e) {
            e.printStackTrace();
        }

2
不错。经过几次重新安装后,令牌停止了刷新,但直接调用getToken确实返回了正确的令牌。 - Vitaliy A

14
尝试重新安装应用程序,首先从您的设备或模拟器中卸载它。这将生成一个新的令牌,因此 onTokenRefresh() 将再次被调用。请保留原文中的HTML标签格式。

13

在我的情况下,我忘记在清单文件中添加网络权限。

<uses-permission android:name="android.permission.INTERNET" />

希望大多数人不会犯这个错误。


4
重新安装解决了我的问题!

4

请确保您已将

apply plugin: 'com.google.gms.google-services'

添加到app.gradle文件的底部


4
try {
    FirebaseInstanceId.getInstance().deleteInstanceId();
} catch (IOException e) {
    e.printStackTrace();
}

onCreate 方法中删除令牌。


Thread t = new Thread() will solve the MAIN_THREAD Exception - Pierre

3

在我的情况下,我尝试了所有方法,但是onTokenRefresh从未被调用。然后我更改了我的WiFi并连接到不同的网络,现在它可以工作了!!之前的WiFi有良好的互联网连接,不知道为什么会发生这种情况。也许这能帮助某些人。


3
我曾经遇到这样的情况,当您在没有网络连接的设备上运行应用程序时,MyFirebaseInstanceIDService不会被调用。 这样,onTokenRefresh()方法就不会被调用。 因此,请确保您的设备在运行应用程序时具有互联网连接,以获取更新的FirebaseToken。
此外,卸载先前的应用程序并重新安装它以获取更新的令牌。 注册令牌将在以下情况下更改:
1)应用程序删除实例ID
2)应用程序恢复到新设备上
3)用户卸载/重新安装应用程序
4)用户清除应用程序数据。

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