Firebase onTokenRefresh () wird nicht aufgerufen


72

In meinem MainActivityProtokoll kann ich sehen, wie das Token verwendet wird, FirebaseInstanceId.getInstance().getToken()und es zeigt das generierte Token an. Aber es scheint so, als ob in meinem, MyFirebaseInstanceIDServicewo es sich erstreckt FirebaseInstanceIdService, das onTokenRefresh()nicht aufgerufen wird, wo in dieser Funktion gesagt wurde, dass das Token hier ursprünglich generiert wird. Ich musste anrufen sendRegistrationToServer(), deshalb versuche ich zu wissen, warum es nicht in die geht onTokenRefresh().

Hier ist mein Code

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);
    }
}

Mögliches Duplikat von Firebase FCM erzwingt das Aufrufen
Machado

2
Bitte lesen Sie die Fragen vollständig durch. Diese Frage ist kein Duplikat der von Ihnen genannten Frage. @ Machado
Wijay Sharma

Antworten:


106

onTokenRefresh in FirebaseInstanceIdService wird nur aufgerufen, wenn ein neues Token generiert wird. Wenn Ihre App zuvor installiert und ein Token generiert wurde, wird onTokenRefresh nicht aufgerufen. Versuchen Sie, die App zu deinstallieren und neu zu installieren, um die Generierung eines neuen Tokens zu erzwingen. Dies würde dazu führen, dass onTokenRefresh aufgerufen wird.

Stellen Sie außerdem sicher, dass Ihr FirebaseInstanceIdService in Ihrer AndroidManifest.xml ordnungsgemäß definiert ist

In Ihrer Manifestdatei.

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

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

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
Die Dokumentation erscheint verwirrend ( firebase.google.com/docs/cloud-messaging/android/client ). Das Registrierungstoken kann sich ändern, wenn: Die App die Instanz-ID löscht und wenn ich FirebaseInstanceId.getInstance () manuell aufrufe. DeleteInstanceId ( ); Ich hatte erwartet, dass ein neues Token generiert wird, aber in diesem Fall passiert eigentlich nichts. OnTokenRefresh wird nie aufgerufen.
WenChao

2
Warum das Token in freigegebenen Einstellungen speichern - wenn Sie FirebaseInstanceId.getInstance (). GetToken () jederzeit aufrufen können, um seinen Wert abzurufen ?
Alexander Farber

@WenChao stellen Sie sicher, dass Sie InstanceID des Spielservices von InstanceID.getInstance(this).deleteInstanceID()aufrufen und es aus dem Hintergrund-Thread aufrufen. Nachdem Sie es erfolgreich gelöscht haben, rufen Sie InstanceID.getInstance(this).getID()an, um ein neues Token zu generieren
Salis

@Alexander Farber, weil Sie den Token nur einmal erhalten können, müssen Sie ihn beibehalten, um ihn später verwenden zu können. Zum Beispiel mache ich eine App, bei der der Benutzer nicht registriert sein muss, aber er ein bestimmtes Update abonnieren möchte. Er kann sich registrieren. Ich kann das Token seines Geräts mit seinen Daten senden, aber wenn ich es bekommen würde Das Token, als er die App zum ersten Mal installierte, wäre nicht möglich.
Sterling Diaz

Ich teste es auf kitkat and aboveGeräten, deren kitkat onTokenRefreshMethode nicht ausgelöst wirdFCM version 11.6.2
Sagar

23

Ich hatte das gleiche Problem wie du. Mein Fehler war folgender: Ich habe meine <service>Tags außerhalb des <application>Tags in der Datei AndroidManifest.xml platziert.

Jetzt sieht meine so aus:

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

Und es funktioniert ohne Probleme.


1
Credits gehen an diesen Thread: stackoverflow.com/questions/37351354/…
viplezer

Tolle Antwort ... ist dies die Facebook-ID, die zurückgegeben wird? ....... weil ich das versuche und einen sehr großen Token bekomme
Juan

Facebook? Feuerbasis? Sie erhalten das Token für Firebase Cloud Messaging in der onTokenRefresh-Methode Ihrer FirebaseInstanceIDService-Unterklasse. Ja, es ist eine lange Zeichenfolge. Mein Token ist 152 Zeichen lang.
Viplezer

Das ist die Lösung für mich.
jet_choong

@viplezer auf meinem KITKATnicht in der Lage, tokenüber seine Arbeit zu kommen. Bitte helfen Sie
Sagar

15

Ja, das kann manchmal passieren.

Rufen Sie die folgende Methode auf, wo immer Sie Ihre fcm-ID erhalten möchten.

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

2
Gut. Nach einigen Neuinstallationen stoppte das Token, um es zu aktualisieren, aber direktes getToken gab das richtige Token zurück.
Vitaliy A

14

Versuchen Sie, die App erneut zu installieren, indem Sie sie zuerst von Ihrem Gerät oder Emulator deinstallieren. Es wird dann ein neues Token generiert, sodass onTokenRefresh () erneut aufgerufen wird.


13

In meinem Fall habe ich vergessen, die Internet-Berechtigung im Manifest hinzuzufügen.

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

Ich hoffe, die meisten Leute machen diesen Fehler nicht.


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

in onCreateMethode zum Löschen des Tokens.


Thread t = new Thread()wird das lösenMAIN_THREAD Exception
Pierre


4

Stellen Sie sicher, dass Sie hinzugefügt haben

Plugin anwenden: 'com.google.gms.google-services'

Dies zum Ende der Datei app.gradle


3

In meinem Fall habe ich alles versucht, onTokenRefreshwurde aber nie angerufen. Dann ändere ich mein WiFi und verbinde mich mit einem anderen Netzwerk . Jetzt hat es funktioniert !!. Vorheriges WiFi hat eine gute Internetverbindung. Ich weiß nicht, warum es passiert ist. Vielleicht kann dies jemandem helfen.


3

Ich habe festgestellt, dass MyFirebaseInstanceIDService nicht aufgerufen wird, wenn Sie Ihre Anwendung auf einem Gerät ausführen, auf dem keine Internetverbindung verfügbar ist. Auf diese Weise wird onTokenRefresh () nicht aufgerufen. Stellen Sie daher sicher, dass Ihr Gerät während der Ausführung Ihrer Anwendung über eine Internetverbindung verfügt, damit das aktualisierte FirebaseToken verwendet werden kann.

Deinstallieren Sie auch die vorherige App und installieren Sie sie erneut, um das aktualisierte Token zu erhalten. Das Registrierungstoken ändert sich, wenn:

1) Die App löscht die Instanz-ID

2) Die App wird auf einem neuen Gerät wiederhergestellt

3) Der Benutzer deinstalliert / installiert die App neu

4) Der Benutzer löscht App-Daten.


3

Es gibt mehrere Gründe, das nicht aufgerufene onTokenRefresh-Methon nicht aufzurufen. Ich habe das aufgelistet und eins nach dem anderen erwähnt.

  1. Bitte stellen Sie sicher, dass Sie die Internetberechtigung hinzugefügt haben

  2. Überprüfen Sie, ob Sie die Datei google-services.json hinzugefügt haben, die von der Google-Konsole im App-Verzeichnis Ihres Projekts generiert wird

Geben Sie hier die Bildbeschreibung ein

  1. Fügen Sie in Ihrer Modul-Gradle-Datei (normalerweise app / build.gradle) die Zeile zum Anwenden des Plugins am Ende der Datei hinzu, um das Gradle-Plugin zu aktivieren:
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) Fügen Sie den Pfad der Play Service-Klasse in die Datei build.gridle auf Projektebene ein

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

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

5) Stellen Sie sicher, dass Sie diesen Dienst in der AndroidManifes-Datei im Anwendungs-Tag hinzugefügt haben

<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) Die onToken-Aktualisierung wird aufgerufen, wenn die Token aktualisiert und die App zum ersten Mal installiert wird. Stellen Sie daher sicher, dass Sie die App manuell gelöscht haben, oder löschen Sie die Daten

7) Stellen Sie sicher, dass Sie den FirebaseMessagingService in Ihrer Serviceklasse erweitert haben

[ Hinweis : Wenn es nicht nur für eine bestimmte Version funktioniert, z. B. für die Android Kitkat-Version, versuchen Sie, die fcm-Version zu ändern.]


auf Kitkat Gerät nicht in der Lage zu bekommentoken FirebaseInstanceId: Token retrieval failed: SERVICE_NOT_AVAILABLE
Sagar

Haben Sie alle Avobe-Probleme überprüft, die ich hier erwähnt habe?
Hoque MD Zahidul

Ja, nur auf dem Kitkat-Gerät funktioniert es nicht. Über Kitkat funktioniert es. Meine FCMVersion ist11.6.2
Sagar

Das Ändern der FCMVersion, um 10.2.1für mich zu arbeiten, ist meine targetSdkVersion 27und Minimum ist16
Sagar

2

Ich habe über eine Stunde damit zu kämpfen, dann habe ich den folgenden Code geändert und es hat plötzlich funktioniert.

Behandeln Sie Ihr refreshedToken als solches:

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();
    }

Versuchen Sie, android: exported = "true"> sowohl zu MyFirebaseMessagingService als auch zu MyFirebaseInstanceIDService im Manifest hinzuzufügen, damit es so aussieht:

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

Deinstallieren Sie Ihre App, erneut installieren, funktioniert. Auf echtem Gerät getestet.

android: exported = "true" ist eine Standardoption, sodass Sie diese auch vollständig entfernen können und sie auf true gesetzt wird.

Auch wenn Sie onTokenRefresh expliziter aufrufen möchten, können Sie dies einfach an einer beliebigen Stelle in Ihrem Code aufrufen:

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

Sie müssen sich nicht mehr darauf verlassen, dass eine Sendung empfangen wird


Sie sagen "android: exported = true", aber das Codebeispiel sagt "android: exported = false". Welches ist es?
Matt Mc

Entschuldigung Mann, aktualisiert und erweitert, danke für den Hinweis
Danjar

2

Ich hatte das gleiche Problem. Mein Gerät (kitkat 4.4.2)konnte onTokenRefresh()aus irgendeinem Grund nicht bekommen . Meine Internetverbindung war perfekt, die Google Play-Dienste waren auf dem neuesten Stand und alle notwendigen Voraussetzungen, damit Firebase funktioniert, wurden erfüllt. Mein Code funktionierte perfekt auf den Geräten 5.0.0und höher. Um dieses Problem zu lösen, musste ich mein Gerät auf die Werkseinstellungen zurücksetzen und die Anwendung begann zu funktionieren. Ich weiß, dass es eine schwierige Maßnahme ist, aber vielleicht kann es jemandem helfen. Es muss einige Probleme oder Konflikte mit anderen Anwendungen geben, die dazu geführt haben, dass sie onTokenRefresh()nicht aufgerufen wurden. Viel Glück!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.