Firebase (FCM) wie man Token bekommt


91

Ich benutze FCM zum ersten Mal.

Ich lade ein Beispiel von firebase / quickstart-android herunter und installiere den FCM-Schnellstart. Aber ich kann kein Token aus dem Protokoll erhalten, auch wenn ich in der App auf die Schaltfläche LOG TOKEN geklickt habe .

Dann versuche ich, eine Nachricht mit der Firebase-Konsole zu senden und auf meinen App-Paketnamen zu zielen. Ich habe eingehende Nachrichten erhalten.

Ich möchte wissen, ob FCM verwendet werden kann. GCM, alles ist in Ordnung.

Lösung:

Weil ich kein Android-Entwickler bin, sondern nur ein Backend-Entwickler. Ich brauche also einige Zeit, um es zu lösen. Meiner Meinung nach gibt es einige Fehler in der Beispiel-App.

Geben Sie hier die Bildbeschreibung ein

Code:

RegistrationIntentService.java

public class RegistrationIntentService extends IntentService {

    private static final String TAG = "RegIntentService";


    public RegistrationIntentService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String token = FirebaseInstanceId.getInstance().getToken();
        Log.i(TAG, "FCM Registration Token: " + token);
    }
}

MyFirebaseInstanceIDService.java

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String TAG = "MyFirebaseIIDService";

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
//        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//        Log.d(TAG, "Refreshed token: " + refreshedToken);
//
//        // TODO: Implement this method to send any registration to your app's servers.
//        sendRegistrationToServer(refreshedToken);
//
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    }
    // [END refresh_token]

    /**
     * Persist token to third-party servers.
     * <p>
     * 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.
    }
}

Fügen Sie dies in der Datei MainActivity.java hinzu.

 Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);

Nach oben , erhalten Sie das Token in Logcat. Aber schließlich finde ich einen bequemen Weg , um es zu bekommen. Verwenden Sie einfach den Debug-Modus, um die Beispiel-App zu installieren, und Sie können das Token erhalten, wenn Sie es zum ersten Mal installieren.

Ich weiß jedoch nicht, warum das Protokoll bei der Installation nicht gedruckt werden kann. Vielleicht mit dem mobilen System verwandt sein.

Und warum kann ich dann keine Benachrichtigung erhalten? FirebaseMessagingService.onMessageReceived hat sendNotification nicht aufgerufen


Wenn das Protokoll getroffen wird, wird das Token in der Beispiel-App
angezeigt

Nein, die Beispiel-App sagte. Das Token wird nur in logcat angezeigt, wenn ich auf die Schaltfläche drücke. Aber ich finde nichts in logcat. @ Shubhank
wyx

Kommentieren Sie diese Zeilen aus String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

Antworten:


119

SCHNELLSTES UND GUTES FÜR PROTOTYP

Die schnelle Lösung besteht darin, es in sharedPrefs zu speichern und diese Logik der onCreateMethode in Ihrer MainActivity oder Klasse hinzuzufügen , die Application erweitert.

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, instanceIdResult -> {
    String newToken = instanceIdResult.getToken();
    Log.e("newToken", newToken);
    getActivity().getPreferences(Context.MODE_PRIVATE).edit().putString("fb", newToken).apply();
});

Log.d("newToken", getActivity().getPreferences(Context.MODE_PRIVATE).getString("fb", "empty :("));

SAUBERER WEG

Eine bessere Option besteht darin, einen Dienst zu erstellen und eine ähnliche Logik beizubehalten. Erstellen Sie zunächst einen neuen Service

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        Log.e("newToken", s);
        getSharedPreferences("_", MODE_PRIVATE).edit().putString("fb", s).apply();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
    }

    public static String getToken(Context context) {
        return context.getSharedPreferences("_", MODE_PRIVATE).getString("fb", "empty");
    }
}

Und fügen Sie es dann der AndroidManifest-Datei hinzu

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

Schließlich können Sie eine statische Methode aus Ihrem Dienst verwenden MyFirebaseMessagingService.getToken(Context);

DAS SCHNELLSTE, ABER VERRINGERT

Log.d("Firebase", "token "+ FirebaseInstanceId.getInstance().getToken());

Es funktioniert immer noch, wenn Sie eine ältere Firebase-Bibliothek als Version 17.xx verwenden


4
Der zweite Ansatz funktioniert jedoch nur, bis die gemeinsamen Einstellungen gelöscht sind. Was passiert, wenn die App-Daten gelöscht werden und dieser Zeichenfolgenwert verloren geht? Android ruft nicht "onNewtoken ()" auf, da es kein neues Token gibt. Aber wie fordern wir dann den Token an? Überall heißt es "benutze nur onNewToken ()", aber diese Methode wird nur ausgeführt, wenn es ein neues Token gibt. Angenommen, diese Methode wurde bereits ausgeführt, aber wir haben uns nicht die Mühe gemacht, das Token zu speichern. Später führen wir eine Überprüfung durch und stellen fest, dass der Token nicht gesetzt ist. Was dann? Wie löse ich FCM aus, um mir das Token erneut mitzuteilen?
JeneralJames


1
Sie können FirebaseInstanceId.getInstance().getInstanceId()stattdessen verwenden FirebaseInstanceId.getInstance().getToken(), siehe diese Antwort
Vadim Kotov

24

Wichtige Informationen.

Wenn der Google Play-Dienst hängen bleibt oder nicht ausgeführt wird, gibt fcm return token = zurück null

Wenn der Wiedergabedienst ordnungsgemäß funktioniert, wird die FirebaseInstanceId.getInstance().getToken()Methode zurückgegebentoken

Log.d("FCMToken", "token "+ FirebaseInstanceId.getInstance().getToken());

Ja, aber das passiert sehr oft
Hoang Duc Tuan

Token wird zwischengespeichert (höchstwahrscheinlich in-mem), nachdem es einmal abgerufen wurde. Das bedeutet also, dass Sie es einmal abrufen oder Firebase dazu bringen müssen, ein anderes Token für Sie erneut auszustellen. Hier erfahren
Sie,

19

Das Team hinter Firebase Android SDK ändert die API ein wenig. Ich habe die "Token to Server" -Logik wie folgt implementiert:

In meiner Instanz von FirebaseMessagingService:

public class FirebaseCloudMessagingService extends FirebaseMessagingService {

    ...

    @Override
    public void onNewToken(String token) {
        // sending token to server here
    }

    ...

}

Beachten Sie, dass sich das Token pro Gerät befindet und von Firebase unabhängig von Ihrer Anmeldelogik aktualisiert werden kann. Wenn Sie also über Anmelde- und Abmeldefunktionen verfügen, müssen Sie zusätzliche Fälle berücksichtigen:

  1. Wenn sich ein neuer Benutzer anmeldet, müssen Sie das Token an den neuen Benutzer binden (an den Server senden). Da das Token möglicherweise während der Sitzung des alten Benutzers aktualisiert wird und der Server das Token des neuen Benutzers nicht kennt.
  2. Wenn sich der Benutzer abmeldet, müssen Sie die Bindung des Tokens aufheben. Weil der Benutzer keine Benachrichtigungen / Nachrichten mehr erhalten sollte.

Mit der neuen API können Sie Token wie folgt erhalten:

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
        @Override
        public void onSuccess(InstanceIdResult instanceIdResult) {
            String token = instanceIdResult.getToken();
            // send it to server
        }
    });

Viel Glück!


Der Versuch, den Wert außerhalb von OnSuccess abzurufen, gibt null an.
DragonFire

Die Anmelde- / Abmeldefunktion hat nichts mit Push-Nachrichten zu tun. Dies ist ein spezifischer Geschäftsanwendungsfall. Beispielsweise möchten Sie möglicherweise abgemeldete Benutzer mit einigen Marketing- / Promo-Benachrichtigungen ansprechen, damit sie sich wieder bei der App anmelden. In diesem Fall benötigen Sie das FCM-Token. Aber die Antwort ist richtig in Bezug auf das Erhalten des Tokens.
Milosmns

@milosmns, Sie haben Recht in Bezug auf Marketing- / Promo-Benachrichtigungen. Es besteht weiterhin die Notwendigkeit, den Token-Status anzuzeigen. Die einfache Lösung wäre, die ungebundenen Token in einer Art Verlaufstabelle zu speichern und dann diese früheren Token zu verwenden, um die Verwendung zum
erneuten Anmelden

Hm, ich bin mir nicht sicher, wie lange Sie dasselbe Token wiederverwenden können und wann genau es ungültig wird. Dies ist eine Untersuchung wert, da Sie diese Verlaufs- / Cache- / Persistenztabelle wohl löschen müssen, sobald Token ungültig werden.
Milosmns

@milosmns, in Firebaseland, verfallen Token nicht, sondern werden erneuert. Wenn Sie eine tokenbezogene Aktivität mit der FCM-API auslösen, wird das bereitgestellte Token überprüft. Wenn das Token ungültig ist, erhalten Sie folgende Fehlermeldung: MissingRegistration oder Fehler: InvalidRegistration. Weitere Fehlercodes finden Sie hier: firebase.google.com/docs/cloud-messaging/…
rzaaeeff

13

Laut doc

Migrieren Sie eine GCM-Client-App zu FCM

onTokenRefresh()

Wird nur aufgerufen, wenn das InstanceID-Token aktualisiert wird

Es wird also nur beim ersten Mal aufgerufen, wenn Sie eine App auf Ihrem Gerät installieren.

Ich empfehle daher, Ihre App manuell zu deinstallieren und erneut zu versuchen

auf jeden Fall werden Sie Token bekommen


2
nicht neu installieren, manuell deinstallieren und dann das Projekt ausführen,
Gaurav

Kommentieren Sie diese Zeilen aus String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

1
@Gaurav, wie kann ich nach dem zweiten Login ein Token bekommen? onTokenRefreshnicht jedes Login aufrufen. Wie kann ich ein Token in meinem Anmeldebildschirm erhalten?
Delavega66

3
@ de_la_vega_66, Sie müssen Ihr Token bei der ersten Anmeldung speichern
Gaurav

Ihr Dienst, der FirebaseInstanceIdService erweitert und über die Rückrufmethode onTokenRefresh () verfügt, MUSS in der Manifest-Datei registriert sein: <service android: name = "com.mypackage.name.MyInstanceIdService" android: exported = "true"> <intent-filter> <action android: name = "com.google.firebase.INSTANCE_ID_EVENT" /> </ intent-filter> </ service>
Kirill Karmazin

9

Versuche dies. Warum benutzt du RegistrationIntentService?

public class FirebaseInstanceIDService extends FirebaseInstanceIdService {    
    @Override
    public void onTokenRefresh() {    
        String token = FirebaseInstanceId.getInstance().getToken();    
        registerToken(token);
    }

    private void registerToken(String token) {

    }
}

8

Diese Zeile sollte Ihnen das Firebase-FCM-Token geben.

String token = FirebaseInstanceId.getInstance().getToken();
Log.d("MYTAG", "This is your Firebase token" + token);

Führen Sie Log.d aus, um es auf dem Android-Monitor auszudrucken.


Es gibt null zurück
Kishan Solanki

7

An Stelle von:

    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
//        Get updated InstanceID token.
//        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//        Log.d(TAG, "Refreshed token: " + refreshedToken);
//
//        TODO: Implement this method to send any registration to your app's servers.
//        sendRegistrationToServer(refreshedToken);
//
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    }
    // [END refresh_token]

Mach das:

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

        // Implement this method to send token to your app's server
       sendRegistrationToServer(refreshedToken);

    }
    // [END refresh_token]

Und noch etwas:

Sie müssen eine sendRegistrationToServer()Methode aufrufen , die das Token auf dem Server aktualisiert, wenn Sie Push-Benachrichtigungen vom Server senden.

AKTUALISIEREN:

Ein neues Firebase-Token wird generiert ( onTokenRefresh()wird aufgerufen), wenn:

  • Die App löscht die Instanz-ID
  • Die App wird auf einem neuen Gerät wiederhergestellt
  • Der Benutzer deinstalliert / installiert die App neu
  • Der Benutzer löscht App-Daten.

Ich musste die Instanz-ID FirebaseInstanceId.getInstance (). DeleteInstanceId () löschen, bekam aber einen SERVICE-
FEHLER

2
Sie müssen FirebaseInstanceId.getInstance().deleteInstanceId()in einem anderen Thread laufen
rockar06

5

Vergessen Sie nicht, dies in Ihre Manifestdatei aufzunehmen, um die Token-ID zu erhalten

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

4

In firebase-messaging:17.1.0und neuer ist der FirebaseInstanceIdService veraltet. Sie können ihn onNewTokenfür die FirebaseMessagingServiceKlasse abrufen, wie unter https://stackoverflow.com/a/51475096/1351469 erläutert

Wenn Sie den Token jedoch jederzeit erhalten möchten, können Sie dies jetzt folgendermaßen tun:

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( this.getActivity(),  new OnSuccessListener<InstanceIdResult>() {
  @Override
  public void onSuccess(InstanceIdResult instanceIdResult) {
    String newToken = instanceIdResult.getToken();
    Log.e("newToken",newToken);
  }
});

Kann dies zurückgegeben werden, so dass die gleiche Funktion an vielen Stellen verwendet werden kann, oder wir müssen kopieren und einfügen, da die Feuerbasis asynchron ist
DragonFire

4

Die Methode getToken()ist veraltet. Sie können getInstanceId()stattdessen verwenden.

Wenn Sie die Ergebnisse bei der Anforderung verarbeiten möchten instanceId(token), überprüfen Sie diesen Code.

    FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(instanceIdResult -> {
    if (instanceIdResult != null) {
        String token = instanceIdResult.getToken();
        if (!TextUtils.isEmpty(token)) {
            Log.d(TAG, "retrieve token successful : " + token);
        }
    } else{
        Log.w(TAG, "instanceIdResult should not be null..");
    }
}).addOnFailureListener(e -> {
    //do something with e
}).addOnCanceledListener(() -> {
    //request has canceled
}).addOnCompleteListener(task -> Log.v(TAG, "task result : " + task.getResult().getToken()));

3

Wenn Sie eine Auth-Funktion von Firebase verwenden, können Sie Token wie folgt verwenden:

//------GET USER TOKEN-------
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getToken(true)
        .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
            public void onComplete(@NonNull Task<GetTokenResult> task) {
                if (task.isSuccessful()) {
                    String idToken = task.getResult().getToken();
                      // ...
                }
            }
        });

Funktioniert gut, wenn Benutzer angemeldet sind. getCurrentUser ()


2

Versuche dies

FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener(OnSuccessListener<InstanceIdResult> { instanceIdResult ->
             fcm_token = instanceIdResult.token}

1

Für diejenigen, die hier landen, ist bis jetzt FirebaseInstanceIdServiceveraltet, verwenden Sie stattdessen:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onNewToken(String token) {
        Log.d("MY_TOKEN", "Refreshed token: " + token);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        // sendRegistrationToServer(token);
    }
}

und in AndroidManifest deklarieren

<application... >

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

1
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
            @Override
            public void onComplete(@NonNull Task<InstanceIdResult> task) {
                if (!task.isSuccessful()) {
                    Log.w(TAG, "getInstanceId failed", task.getException());
                    return;
                }

                // Get new Instance ID token
                String **token** = task.getResult().getToken();

            }
        });

-1

In Firebase (FCM) können Sie Folgendes verwenden, um das Token abzurufen:

FirebaseInstanceId.getInstance().getToken();

2
Die Methode getToken () ist veraltet! Die beste Antwort kommt jetzt von @rzaaeeff.
Damiii

-9
Settings.Secure.getString(getContentResolver(),
                     Settings.Secure.ANDROID_ID);

Dieser Code dient zum Abrufen der Android-ID des Geräts, nicht des Firebase-Tokens.
Syed Afeef
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.