Firebase onTokenRefresh() не вызывается

В моем MainActivityв моем журнале я вижу токен, используя FirebaseInstanceId.getInstance().getToken(), и он отображает сгенерированный токен. Но вроде как в моем MyFirebaseInstanceIDService где он расширяется до FirebaseInstanceIdService, onTokenRefresh() не вызывается, где в этой функции было сказано, что токен изначально генерируется здесь. Мне нужно было позвонить 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);
    }
}

person natsumiyu    schedule 26.05.2016    source источник
comment
Возможный дубликат Firebase FCM принудительно вызывает onTokenRefresh()   -  person Machado    schedule 15.08.2016
comment
Пожалуйста, прочитайте вопросы полностью. Этот вопрос не дублирует вопрос, который вы упомянули. @Мачадо   -  person Wijay Sharma    schedule 06.03.2018


Ответы (13)


onTokenRefresh в FirebaseInstanceIdService вызывается только при создании нового токена. Если ваше приложение было ранее установлено и сгенерировано токен, onTokenRefresh не будет вызываться. Попробуйте удалить и переустановить приложение, чтобы принудительно сгенерировать новый токен, это приведет к вызову onTokenRefresh.

Также убедитесь, что ваш FirebaseInstanceIdService правильно определен в вашем AndroidManifest.xml.

В вашем файле манифеста.

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

}}
person Sagar Gangawane    schedule 26.05.2016
comment
Документация кажется запутанной (firebase.google.com/docs/cloud-messaging/android /client), он говорит, что токен регистрации может измениться, когда: приложение удалит идентификатор экземпляра, и если я вручную вызову FirebaseInstanceId.getInstance().deleteInstanceId(); Я ожидал, что будет сгенерирован новый токен, но в этом случае на самом деле ничего не происходит, onTokenRefresh никогда не вызывается. - person WenChao; 04.08.2016
comment
Зачем сохранять токен в общих настройках, если можно вызвать FirebaseInstanceId.getInstance().getToken() в любое время, чтобы получить его значение? - person Alexander Farber; 29.05.2017
comment
@WenChao убедитесь, что вы вызываете InstanceID playservice с помощью InstanceID.getInstance(this).deleteInstanceID() и вызываете его из фонового потока, после того, как вы успешно удалите его, вызовите InstanceID.getInstance(this).getID() для создания нового токена - person Salis; 03.06.2017
comment
@ Александр Фарбер, это потому, что вы можете получить токен только один раз, вам нужно сохранить его, чтобы использовать его позже. Например, я делаю приложение, которое не требует регистрации пользователя, но если он хочет подписаться на определенное обновление, он может зарегистрироваться, я могу отправить токен своего устройства с его данными, но если бы я получил токен, когда он впервые установил приложение, это было бы невозможно. - person Sterling Diaz; 14.11.2017
comment
Я тестирую его на kitkat and above устройствах на kitkat метод onTokenRefresh не срабатывает FCM version 11.6.2 - person Sagar; 21.11.2018

У меня была такая же проблема, как у вас. Моя ошибка заключалась в следующем: я поместил свои теги <service> вне тега <application> в файле AndroidManifest.xml.

Теперь моя выглядит так:

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

И работает без проблем.

person viplezer    schedule 26.05.2016
comment
Кредиты относятся к этой теме: stackoverflow.com/questions/37351354/ - person viplezer; 26.05.2016
comment
отличный ответ ... это идентификатор facebook, который возвращается? ... потому что я пытаюсь сделать это, и я получаю очень большой токен - person Juan; 15.10.2016
comment
Фейсбук? База данных? Вы получаете токен для Firebase Cloud Messaging в методе onTokenRefresh подкласса FirebaseInstanceIDService, и да, это длинная строка, мой токен имеет длину 152 символа. - person viplezer; 19.10.2016
comment
это решение для меня. - person jet_choong; 29.07.2017
comment
@viplezer на моем KITKAT не может заставить token работать выше. пожалуйста помоги - person Sagar; 20.11.2018

Да, это может происходить несколько раз.

Пожалуйста, вызовите следующий метод везде, где вы хотите получить свой идентификатор fcm.

    try {
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
            Log.d("Firbase id login", "Refreshed token: " + refreshedToken);
        } catch (Exception e) {
            e.printStackTrace();
        }
person Surendar D    schedule 09.11.2016
comment
Хороший. После нескольких переустановок токен перестал обновляться, но прямой getToken вернул правильный токен. - person Vitaliy A; 02.03.2017

Попробуйте переустановить приложение, предварительно удалив его со своего устройства или эмулятора. Затем он сгенерирует новый токен, поэтому onTokenRefresh() будет вызываться снова.

person faruk    schedule 29.11.2016

В моем случае я забыл добавить разрешение на доступ в Интернет в манифест,

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

Надеюсь, что большинство людей не совершит эту ошибку.

person Sreedhu Madhu    schedule 25.11.2016

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

в методе onCreate удалить токен.

person pru    schedule 22.10.2016
comment
Thread t = new Thread() решит MAIN_THREAD Exception - person Pierre; 22.02.2018

Переустановка помогла мне!

person Sterling Diaz    schedule 14.11.2017

Убедитесь, что вы добавили

применить плагин: 'com.google.gms.google-services'

это в нижней части файла app.gradle

person user2837615    schedule 12.04.2018

В моем случае я пробовал все, но onTokenRefresh никогда не вызывался. Затем я переключаю свой WiFi и подключаюсь к другой сети. Теперь это сработало!! Предыдущий Wi-Fi имеет хорошее подключение к Интернету, не знаю, почему это происходит. Может быть, это может помочь кому-то.

person karanatwal.github.io    schedule 01.08.2017

Я обнаружил, что MyFirebaseInstanceIDService не вызывается, когда вы запускаете свое приложение на устройстве, где подключение к Интернету недоступно. Таким образом, onTokenRefresh() не вызывается. Поэтому убедитесь, что ваше устройство должно иметь подключение к Интернету во время запуска приложения для получения обновленного FirebaseToken.

Также удалите предыдущее приложение и переустановите его, чтобы получить обновленный токен. Токен регистрации меняется, когда:

1) Приложение удаляет идентификатор экземпляра

2) Приложение восстанавливается на новом устройстве

3) Пользователь удаляет/переустанавливает приложение

4) Пользователь очищает данные приложения.

person Sheharyar Ejaz    schedule 21.03.2018

Я боролся с этим больше часа, затем я изменил следующий код, и он внезапно заработал.

обрабатывать ваш refreshedToken как таковой:

String refreshedToken;
    try {
        refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);
        Localytics.setPushRegistrationId(refreshedToken);
    } catch (Exception e) {
        Log.d(TAG, "Refreshed token, catch: " + e.toString());
        e.printStackTrace();
    }

Попробуйте добавить android:exported="true"> в MyFirebaseMessagingService и MyFirebaseInstanceIDService в манифесте, чтобы это выглядело так:

<service
        android:name="com.localytics.android.sample.fcm.MyFirebaseMessagingService"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

    <service
        android:name="com.localytics.android.sample.fcm.MyFirebaseInstanceIDService"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>

Удалите приложение, установите снова, сработало. Проверено на реальном устройстве.

android:exported="true" - это параметр по умолчанию, поэтому вы также можете полностью удалить его, и для него будет установлено значение true.

Кроме того, если вы хотите вызвать onTokenRefresh более явно, вы можете просто вызвать его в любом месте вашего кода:

String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Localytics.setPushRegistrationId(refreshedToken);

Вам больше не нужно полагаться на получение трансляции

person danjar    schedule 23.03.2018
comment
Вы говорите android:exported=true, но пример кода говорит android:exported=false. Что он? - person Matt Mc; 01.04.2018
comment
извините, человек, обновленный и расширенный, спасибо, что указали на это - person danjar; 02.04.2018

Есть несколько причин, по которым метод onTokenRefresh не вызывается. Я перечислил это и упоминаю одно за другим.

  1. Пожалуйста, убедитесь, что вы добавили разрешение на доступ в Интернет

  2. check have you added the google-services.json file that generate from google console inside of app directory in your project

введите здесь описание изображения

  1. В файл вашего модуля Gradle (обычно app/build.gradle) добавьте строку применения плагина внизу файла, чтобы включить плагин Gradle:
apply plugin: 'com.android.application'

android {
  // ...
}

dependencies {
  // ...
  implementation 'com.google.firebase:firebase-core:16.0.4'

  // Getting a "Could not find" error? Make sure you have
  // added the Google maven respository to your root build.gradle
}

// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'

4) добавьте путь к классу службы воспроизведения в файле build.gridle уровня проекта.

buildscript {
    // ...
    dependencies {
        // ...
        classpath 'com.google.gms:google-services:4.1.0' // google-services plugin
    }
}

allprojects {
    // ...
    repositories {
        // ...
        google() // Google's Maven repository
    }
}

5) Убедитесь, что вы добавили эти службы в файл AndroidManifes внутри тега приложения.

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

6) onToken refresh is called when token refresh and when install the app for the first so make sure you have deleted the app manually or clear the data

7) Убедитесь, что вы расширяете FirebaseMessagingService в своем классе обслуживания.

[Примечание. Если это не работает только для определенной версии, например, для версии Android Kitkat, попробуйте изменить версию fcm.]

person Hoque MD Zahidul    schedule 26.10.2018
comment
на устройстве kitkat не удалось получить token FirebaseInstanceId: Token retrieval failed: SERVICE_NOT_AVAILABLE - person Sagar; 21.11.2018
comment
Вы проверили все проблемы с авобе, которые я здесь упомянул? - person Hoque MD Zahidul; 21.11.2018
comment
да, только на устройстве kitkat он не работает, остальные выше kitkat работают, моя FCM версия 11.6.2 - person Sagar; 21.11.2018
comment
Изменение версии FCM на 10.2.1 сработало для меня, моя targetSdkVersion 27, а минимум 16 - person Sagar; 21.11.2018

У меня такая же проблема. Моему устройству(kitkat 4.4.2) по какой-то причине не удалось получить onTokenRefresh(). Мое подключение к Интернету было идеальным, сервисы Google Play были обновлены, и все необходимые условия для работы Firebase были соблюдены. Мой код отлично работал на устройствах 5.0.0 и выше. Чтобы решить эту проблему, мне пришлось сбросить настройки устройства до заводских, и приложение заработало. Я знаю, что это жесткая мера, но, возможно, это может помочь кому-то. Должны быть какие-то проблемы или конфликт с другим приложением, из-за которого onTokenRefresh() не вызывается. Удачи!

person Valiyor Irismetov    schedule 17.04.2018