Firebase (FCM) nasıl token alınır


98

FCM'yi ilk kullanışım.

Firebase / quickstart-android'den bir örnek indiriyorum ve FCM Quickstart'ı kuruyorum . Ancak günlükten herhangi bir belirteç alamıyorum, hatta uygulamadaki LOG TOKEN düğmesine bile basamıyorum .

Ardından Firebase konsoluyla bir mesaj göndermeye çalışıyorum ve uygulama paketi adımı hedeflemeye ayarlıyorum. Gelen mesajlarım var.

FCM'nin kullanılabileceğini bilmek istiyorum GCM her şey yolunda.

Çözüm:

Çünkü ben bir Android geliştiricisi değilim, sadece bir arka uç geliştiricisi. Bu yüzden çözmem biraz zaman alıyor. Bence örnek uygulamada bazı hatalar var.

görüntü açıklamasını buraya girin

Kod :

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

Bunu MainActivity.java'ya ekleyin.

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

Yukarıdakileri yaptıktan sonra , Token'ı Logcat'te alırsınız. Ama sonunda, onu elde etmenin uygun bir yolunu buldum . Örnek uygulamayı yüklemek için sadece hata ayıklama modunu kullanın ve jetonu ilk kez yüklediğinizde alabilirsiniz.

Ancak günlüğü yüklediğimde neden yazdıramadığını bilmiyorum. Belki mobil sistemle ilgili olabilir.

Ve sonra neden Bildirimi alamıyorum. FirebaseMessagingService.onMessageReceived aramadım sendNotification



Hayır, örnek uygulama belirteci logcat'te yalnızca düğmeye basarsam belirteci gösterecek. Ama logcat'te hiçbir şey bulamadım. @ Shubhank
wyx

bu satırları uncomment String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

Yanıtlar:


129

PROTOTİP İÇİN EN HIZLI VE İYİ

Hızlı çözüm, bunu sharedPrefs içinde depolamak ve bu mantığı onCreateMainActivity veya uygulamayı genişleten sınıfınızdaki yönteme eklemektir.

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

TEMİZ YOL

Daha iyi bir seçenek, bir hizmet oluşturmak ve benzer bir mantık içinde kalmaktır. Öncelikle yeni Hizmet oluşturun

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

Ve sonra AndroidManifest dosyasına ekleyin

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

Son olarak, Hizmetinizden statik bir yöntem kullanabilirsiniz. MyFirebaseMessagingService.getToken(Context);

EN HIZLI AMA UYGUN DEĞİL

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

17.xx sürümünden daha eski firebase kitaplığını kullandığınızda hala çalışıyor


6
Ancak ikinci yaklaşım yalnızca paylaşılan tercihler temizlenene kadar işe yarar. Ya uygulama verileri temizlenirse ve bu dize değeri kaybolursa? Android, yeni jeton olmadığından "onNewtoken ()" çağırmaz . Peki jetonu nasıl talep edeceğiz? Her yerde "sadece onNewToken () kullan" diyor, ancak bu yöntem yalnızca yeni bir belirteç olduğunda çalışır . Diyelim ki bu yöntem zaten çalışıyor, ancak jetonu saklamakla uğraşmadık. Daha sonra bir kontrol yapıyoruz ve jetonun ayarlanmadığını görüyoruz, o zaman ne olacak? Jetonu tekrar söylemesi için FCM'yi nasıl tetiklerim?
JeneralJames


1
Bunun FirebaseInstanceId.getInstance().getInstanceId()yerine kullanabilirsiniz FirebaseInstanceId.getInstance().getToken(), bu cevabı görün
Vadim Kotov

@JeneralJames, bir kullanıcı uygulama verilerini temizlerse onNewToken, buradaki belgelerden her zaman tetiklenecektir firebase.google.com/docs/cloud-messaging/android/…
sarah

26

Firebase Android SDK'nın arkasındaki ekip, API'yi biraz değiştiriyor. "Token to Server" mantığını şöyle uyguladım:

FirebaseMessagingService örneğimde:

public class FirebaseCloudMessagingService extends FirebaseMessagingService {

    ...

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

    ...

}

Jetonun cihaz başına olduğunu ve giriş mantığınızdan bağımsız olarak Firebase tarafından güncellenebileceğini unutmayın. Dolayısıyla, Oturum Açma ve Oturumu Kapatma işlevlerine sahipseniz, ek durumları göz önünde bulundurmanız gerekir:

  1. Yeni bir kullanıcı oturum açtığında, jetonu yeni kullanıcıya bağlamanız (sunucuya göndermeniz) gerekir. Çünkü jeton, eski kullanıcının oturumu sırasında güncellenebilir ve sunucu yeni kullanıcının jetonunu bilmez.
  2. Kullanıcı oturumu kapattığında, belirtecin bağlantısını kaldırmanız gerekir. Çünkü kullanıcı artık bildirim / mesaj almamalıdır.

Yeni API kullanarak şu şekilde belirteç alabilirsiniz:

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

İyi şanslar!


OnSuccess dışındaki değeri elde etmeye çalışmak boş veriyor.
DragonFire

Oturum açma / oturum kapatma işlevinin Push mesajlarıyla ilgisi yoktur, bu belirli bir iş kullanım durumudur. Örneğin, uygulamada tekrar oturum açmalarını sağlamak için bazı pazarlama / promosyon bildirimleriyle oturum kapatılan kullanıcıları hedeflemek isteyebilirsiniz, bu durumda FCM jetonuna ihtiyacınız olacaktır. Ancak jetonu almak açısından cevap doğru.
milosmns

@milosmns, pazarlama / promosyon bildirimleri konusunda haklısınız. Yine de token durumunun bir göstergesine ihtiyaç vardır. Basit çözüm, bağlanmamış jetonları bir tür geçmiş tablosunda saklamak ve ardından bu eski jetonları tekrar oturum açma kullanımını teşvik etmek için kullanmak olacaktır.
rzaaeeff

Hm Aslında aynı jetonu ne kadar süreyle yeniden kullanabileceğinizden ve tam olarak ne zaman geçersiz kılındığından emin değilim. Belirteçler geçersiz hale geldiğinde bu geçmiş / önbellek / kalıcılık tablosunu temizlemeniz gerekeceğinden, bu araştırmaya değer.
milosmns

@milosmns, Firebaseland'da jetonların süresi dolmaz, aksine yenilenir. FCM API ile jetonla ilgili herhangi bir etkinliği tetiklediğinizde, sağlanan jeton doğrulanır. Belirteç geçersizse, şu hatayı alırsınız: MissingRegistration veya error: InvalidRegistration. Daha fazla hata kodunu burada bulabilirsiniz: firebase.google.com/docs/cloud-messaging/…
rzaaeeff

24

Önemli bilgi.

google oyun hizmeti kilitlendi veya çalışmıyorsa, fcm dönüş belirteci = null

Oyun hizmeti düzgün çalışıyorsa, FirebaseInstanceId.getInstance().getToken()yöntem geri dönertoken

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

Evet, ama bu çok sık oluyor
Hoang Duc Tuan

Belirteç, bir kez getirildikten sonra önbelleğe alınır (büyük olasılıkla mem içinde). Yani bu, onu bir kez getirmeniz veya Firebase'in sizin için bir şekilde başka bir jetonu yeniden düzenlemesi gerektiği anlamına gelir. Stackoverflow.com/a/51630819/2102748
milosmns

13

Doktora göre

Bir GCM istemci uygulamasını FCM'ye taşıma

onTokenRefresh()

yalnızca InstanceID belirteci güncellendiğinde çağrılır

Bu nedenle, yalnızca cihazınıza bir uygulama yüklediğinizde arar.

Bu yüzden lütfen uygulamanızı manuel olarak kaldırmanızı ve tekrar çalıştırmayı denemenizi öneririm.

kesinlikle TOKEN alacaksın


2
yeniden yüklemeyin, elle kaldırın ve ardından projeyi çalıştırın,
Gaurav

bu satırları uncomment String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

1
@Gaurav, ikinci girişten sonra nasıl token alabilirim? onTokenRefreshher girişi aramamak. giriş ekranımda nasıl belirteç alabilirim?
delavega66

3
@ de_la_vega_66, İlk girişte jetonunuzu saklamanız gerekiyor
Gaurav

FirebaseInstanceIdService'i genişleten ve onTokenRefresh () geri arama yöntemine sahip olan Hizmetiniz Manifest dosyasına kaydedilmelidir ZORUNLU: <service android: name = "com.mypackage.name.MyInstanceIdService" android: exported = "true"> <intent-filter> <eylem android: name = "com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
Kirill Karmazin

9

Bunu dene. Neden Kullandığınız RegistrationIntentService?

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

    private void registerToken(String token) {

    }
}

8

Bu satır size firebase FCM jetonunu vermelidir.

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

Android monitöre yazdırmak için Log.d yapın.


Null döndürüyor
Kishan Solanki

7

Bunun yerine:

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

Bunu yap:

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

Ve bir şey daha:

sendRegistrationToServer()Sunucudan push bildirimleri gönderiyorsanız, sunucuda jetonu güncelleyecek yöntemi çağırmanız gerekir .

GÜNCELLEME:

Yeni Firebase jetonu şu durumlarda oluşturulur ( onTokenRefresh()çağrılır):

  • Uygulama, Örnek Kimliğini siler
  • Uygulama yeni bir cihaza geri yüklendi
  • Kullanıcı uygulamayı kaldırır / yeniden yükler
  • Kullanıcı, uygulama verilerini temizler.

Örnek Kimliğini FirebaseInstanceId.getInstance () silmem gerekti. DeleteInstanceId () ancak bir HİZMET HATASI aldım,
Hardik9850

2
FirebaseInstanceId.getInstance().deleteInstanceId()Başka bir İş Parçacığında
koşmanız

6

Aynı zamanda belirteç kimliğini almak için bunu manifest dosyanıza eklemeyi unutmayın.

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

5

Yöntem getToken()kullanımdan kaldırılmıştır. KullanabilirsinizgetInstanceId() yerine .

Talep ederken sonuçları işlemek istiyorsanız instanceId(token), bu kodu kontrol edin.

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

4

Gelen firebase-messaging:17.1.0ve FirebaseInstanceIdService kullanımdan kaldırılmıştır daha yeni, alabileceğiniz onNewTokenüzerinde FirebaseMessagingServiceüzerinde açıklandığı gibi sınıfının https://stackoverflow.com/a/51475096/1351469

Ancak jetonu istediğiniz zaman almak istiyorsanız, şimdi bunu şu şekilde yapabilirsiniz:

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

Bu iade edilebilir mi, böylece aynı işlev birçok yerde kullanılabilir veya firebase'in eşzamansız doğası nedeniyle kopyalayıp yapıştırmamız gerekir
DragonFire

3

Firebase'in bazı kimlik doğrulama işlevlerini kullanıyorsanız, bunu kullanarak jeton alabilirsiniz:

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

Kullanıcı oturum açtıysa iyi çalışın. getCurrentUser ()


2

bunu dene

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

1

buraya FirebaseInstanceIdServiceinenler için şimdiye kadar kullanımdan kaldırıldı, bunun yerine şunu kullanın:

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

ve AndroidManifest'te beyan edin

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

            }
        });

0

FirebaseInstanceId.getInstance().getInstanceId()Olduğu kullanımdan kaldırıldı . Dayanarak Firebase belgenin , aşağıdaki kodu kullanarak jetonu mevcut kayıt alabilirsiniz:

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

-1

Jetonu almak için Firebase'de (FCM) aşağıdakileri kullanabilirsiniz:

FirebaseInstanceId.getInstance().getToken();

2
getToken () yöntemi kullanımdan kaldırıldı! Şimdi en iyi yanıt @ rzaaeeff'ten.
Damiii

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

Bu kod, firebase jetonunu değil, cihazın android kimliğini almak içindir.
Syed Afeef
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.