Firebase (FCM) comment obtenir un jeton


92

C'est la première fois que j'utilise FCM.

Je télécharge un échantillon de firebase / quickstart-android et j'installe le FCM Quickstart. Mais je ne peux pas obtenir de jeton du journal, même appuyez sur le bouton LOG TOKEN dans l'application.

Ensuite, j'essaie d'envoyer un message avec la console Firebase et de définir le ciblage du nom de mon package d'application. J'ai reçu des messages entrants.

Je veux savoir si FCM peut être utilisé? GCM tout est ok.

Solution:

Parce que je ne suis pas un développeur Android, juste un développeur backend. Il me faut donc un certain temps pour le résoudre. À mon avis, il y a quelques bugs dans l'exemple d'application.

entrez la description de l'image ici

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

Ajoutez ceci dans le fichier MainActivity.java.

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

Après avoir fait ci-dessus, vous obtenez le jeton dans Logcat. Mais finalement, je trouve un moyen pratique de l'obtenir. Utilisez simplement le mode débogage pour installer l'exemple d'application et vous pourrez obtenir le jeton lors de la première installation.

Mais je ne sais pas pourquoi il ne peut pas imprimer le journal lorsque je l'installe. Peut-être être lié au système mobile.

Et puis pourquoi je ne peux pas obtenir la notification. FirebaseMessagingService.onMessageReceived n'a pas appelé sendNotification


si le journal est atteint, il affichera le jeton avec lui dans l'exemple d'application
Shubhank

Non, a dit l'exemple d'application. Il n'affichera le jeton dans logcat que si j'appuie sur le bouton. Mais je ne trouve rien dans logcat. @ Shubhank
wyx

décommenter ces lignes String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

Réponses:


120

PLUS RAPIDE ET BON POUR LE PROTOTYPE

La solution rapide consiste à le stocker dans sharedPrefs et à ajouter cette logique à la onCreateméthode de votre MainActivity ou de la classe qui étend Application.

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 :("));

UNE MANIÈRE PLUS PROPRE

Une meilleure option consiste à créer un service et à conserver une logique similaire. Commencez par créer un nouveau 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");
    }
}

Et puis ajoutez-le au fichier AndroidManifest

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

Enfin, vous pouvez utiliser une méthode statique de votre service MyFirebaseMessagingService.getToken(Context);

LE PLUS RAPIDE MAIS DÉPRECÉ

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

Cela fonctionne toujours lorsque vous utilisez une bibliothèque Firebase plus ancienne que la version 17.xx


6
Mais la deuxième approche ne fonctionne que jusqu'à ce que les préférences partagées soient effacées. Que faire si les données de l'application sont effacées et que la valeur de la chaîne est perdue? Android n'appelle pas "onNewtoken ()" car il n'y a pas de nouveau jeton. Mais alors comment demander le jeton? Partout, il est dit "utilisez simplement onNewToken ()" mais cette méthode ne s'exécute que lorsqu'il y a un nouveau jeton. Disons que cette méthode a déjà été exécutée, mais nous n'avons pas pris la peine de stocker le jeton. Plus tard, nous effectuons une vérification et voyons que le jeton n'est pas défini, que faire alors? Comment faire pour que FCM me répète le jeton?
JeneralJames


1
Vous pouvez utiliser à la FirebaseInstanceId.getInstance().getInstanceId()place de FirebaseInstanceId.getInstance().getToken(), voir cette réponse
Vadim Kotov

24

Une information important.

si le service google play est suspendu ou ne fonctionne pas, alors le jeton de retour fcm = null

Si le service de lecture fonctionne correctement, la FirebaseInstanceId.getInstance().getToken()méthode retournetoken

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

Oui, mais cela arrive très souvent
Hoang Duc Tuan

Le jeton est mis en cache (in-mem très probablement) après avoir été récupéré une fois. Cela signifie donc que vous devez le récupérer une fois ou demander à Firebase de réémettre un autre jeton pour vous d'une manière ou d'une autre. Voir ici pour savoir comment récupérer manuellement stackoverflow.com/a/51630819/2102748
milosmns

20

L'équipe derrière Firebase Android SDK change un peu l'API. J'ai implémenté la logique «Token to Server» comme ceci:

Dans mon instance de FirebaseMessagingService:

public class FirebaseCloudMessagingService extends FirebaseMessagingService {

    ...

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

    ...

}

Gardez à l'esprit que le jeton est par appareil et qu'il peut être mis à jour par Firebase quelle que soit votre logique de connexion. Donc, si vous avez la fonctionnalité de connexion et de déconnexion, vous devez prendre en compte des cas supplémentaires:

  1. Lorsqu'un nouvel utilisateur se connecte, vous devez lier le jeton au nouvel utilisateur (l'envoyer au serveur). Parce que le jeton peut être mis à jour pendant la session de l'ancien utilisateur et que le serveur ne connaît pas le jeton du nouvel utilisateur.
  2. Lorsque l'utilisateur se déconnecte, vous devez dissocier le jeton. Parce que l'utilisateur ne devrait plus recevoir de notifications / messages.

En utilisant la nouvelle API, vous pouvez obtenir un jeton comme celui-ci:

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

Bonne chance!


Essayer d'obtenir la valeur en dehors d'OnSuccess donne null.
DragonFire

La fonctionnalité de connexion / déconnexion n'a rien à voir avec les messages Push, il s'agit d'un cas d'utilisation métier spécifique. Par exemple, vous pouvez cibler les utilisateurs déconnectés avec des notifications marketing / promotionnelles pour les inciter à se reconnecter à l'application, auquel cas vous aurez besoin du jeton FCM. Mais la réponse est correcte en termes d'obtention du jeton.
milosmns

@milosmns, vous avez raison en termes de notifications marketing / promo. Une indication de l'état du jeton est toujours nécessaire. La solution simple serait de stocker les jetons non liés dans une sorte de table d'historique, puis d'utiliser ces jetons passés pour encourager l'utilisation à se
reconnecter

Hm, je ne sais pas combien de temps vous pouvez réutiliser le même jeton et quand exactement il est invalidé. Cela vaut la peine d'être étudié, car je suppose que vous devrez effacer cette table d'historique / cache / persistance une fois que les jetons deviennent invalides.
milosmns le

@milosmns, dans Firebaseland, les jetons n'expirent pas mais sont plutôt renouvelés. Lorsque vous déclenchez une activité liée au jeton avec l'API FCM, le jeton fourni est validé. Si le jeton n'est pas valide, vous recevrez une erreur: MissingRegistration ou une erreur: InvalidRegistration. Vous pouvez trouver plus de codes d'erreur ici: firebase.google.com/docs/cloud-messaging/…
rzaaeeff

13

Selon doc

Migrer une application client GCM vers FCM

onTokenRefresh()

Appelé uniquement si le jeton InstanceID est mis à jour

Ainsi, il n'appellera que la première fois lorsque vous installez une application sur votre appareil.

Je suggère donc de désinstaller manuellement votre application et d'essayer de l'exécuter à nouveau

certainement vous obtiendrez TOKEN


2
ne pas réinstaller, désinstaller manuellement puis exécuter le projet,
Gaurav

décommenter ces lignes String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

1
@Gaurav, comment puis-je obtenir un jeton après la deuxième connexion? onTokenRefreshne pas appeler chaque connexion. comment puis-je obtenir un jeton dans mon écran de connexion?
delavega66

3
@ de_la_vega_66, Vous devez stocker votre token lors de la première connexion
Gaurav

Votre service qui étend FirebaseInstanceIdService et a la méthode de rappel onTokenRefresh () DOIT être enregistré dans le fichier manifeste: <service android: name = "com.mypackage.name.MyInstanceIdService" android: exporté = "true"> <intent-filter> <action android: name = "com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
Kirill Karmazin

9

Essaye ça. Pourquoi utilisez-vous RegistrationIntentService?

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

    private void registerToken(String token) {

    }
}

8

Cette ligne devrait vous procurer le jeton FCM Firebase.

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

Faites Log.d pour l'imprimer sur le moniteur Android.


Il retourne null
Kishan Solanki

7

Au lieu de cela:

    // [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]

Faites ceci:

    // [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]

Et encore une chose:

Vous devez appeler la sendRegistrationToServer()méthode qui mettra à jour le jeton sur le serveur, si vous envoyez des notifications push depuis le serveur.

METTRE À JOUR:

Un nouveau jeton Firebase est généré ( onTokenRefresh()est appelé) lorsque:

  • L'application supprime l'ID d'instance
  • L'application est restaurée sur un nouvel appareil
  • L'utilisateur désinstalle / réinstalle l'application
  • L'utilisateur efface les données de l'application.

J'ai dû supprimer l'ID d'instance FirebaseInstanceId.getInstance (). DeleteInstanceId () mais j'ai eu une ERREUR DE SERVICE,
Hardik9850

2
Vous devez exécuter FirebaseInstanceId.getInstance().deleteInstanceId()dans un autre fil de discussion
rockar06

5

En même temps, n'oubliez pas de l'inclure dans votre fichier manifeste pour recevoir l'identifiant du jeton

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

4

Dans firebase-messaging:17.1.0et plus récent le FirebaseInstanceIdService est obsolète, vous pouvez obtenir le onNewTokensur la FirebaseMessagingServiceclasse comme expliqué sur https://stackoverflow.com/a/51475096/1351469

Mais si vous voulez simplement obtenir le jeton à tout moment, vous pouvez maintenant le faire comme ceci:

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

Cela peut-il être retourné, afin que la même fonction puisse être utilisée à de nombreux endroits ou nous devons copier et coller en raison de la nature asynchrone de firebase
DragonFire

4

La méthode getToken()est obsolète. Vous pouvez utiliser à la getInstanceId()place.

Si vous souhaitez gérer les résultats lors de la demande instanceId(token), vérifiez ce 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

Si vous utilisez une fonction d'authentification de Firebase, vous pouvez prendre un jeton en utilisant ceci:

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

Fonctionne bien si l'utilisateur est connecté. getCurrentUser ()


2

essaye ça

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

1

pour ceux qui atterrissent ici, jusqu'à présent FirebaseInstanceIdServiceest obsolète maintenant, utilisez à la place:

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

et déclarer dans AndroidManifest

<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

Vous pouvez utiliser les éléments suivants dans Firebase (FCM) pour obtenir le jeton:

FirebaseInstanceId.getInstance().getToken();

2
La méthode getToken () est obsolète! La meilleure réponse, maintenant, est de @rzaaeeff.
Damiii

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

Ce code sert à obtenir l'ID Android de l'appareil, pas le jeton Firebase.
Syed Afeef
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.