Firebase (FCM) cara mendapatkan token

98

Ini pertama kalinya saya menggunakan FCM.

Saya mendownload sampel dari firebase / quickstart-android dan menginstal FCM Quickstart. Tetapi saya tidak bisa mendapatkan token apa pun dari log bahkan menekan tombol LOG TOKEN di aplikasi.

Kemudian saya mencoba mengirim pesan dengan Firebase console dan menetapkan untuk menargetkan nama paket aplikasi saya. Saya mendapat pesan masuk.

Saya ingin tahu apakah FCM dapat digunakan? GCM semuanya baik-baik saja.

Larutan:

Karena saya bukan pengembang Android, hanya pengembang backend. Jadi saya butuh waktu untuk menyelesaikannya. Menurut saya, ada beberapa bug di aplikasi sampel.

masukkan deskripsi gambar di sini

Kode:

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

Tambahkan ini di MainActivity.java.

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

Setelah melakukan di atas, Anda mendapatkan Token di Logcat. Tapi akhirnya, saya menemukan cara yang mudah untuk mendapatkannya. Cukup gunakan mode debug untuk menginstal aplikasi sampel dan Anda bisa mendapatkan token saat pertama kali menginstalnya.

Tetapi saya tidak tahu mengapa itu tidak dapat mencetak log ketika saya menginstalnya. Mungkin terkait dengan sistem seluler.

Dan mengapa saya tidak bisa mendapatkan Notifikasi. FirebaseMessagingService.onMessageReceived tidak memanggil sendNotification

wyx
sumber
jika log dipukul, itu akan menunjukkan token dengan itu di aplikasi sampel
Shubhank
Tidak, kata aplikasi sampel. Itu hanya akan menampilkan token di logcat jika saya menekan tombol. Tapi saya tidak menemukan apa pun di logcat. @ Shubhank
wyx
hapus komentar baris ini String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav

Jawaban:

130

TERCEPAT DAN BAGUS UNTUK PROTOTYPE

Solusi cepatnya adalah menyimpannya di sharedPrefs dan menambahkan logika ini ke onCreatemetode di MainActivity atau kelas Anda yang memperluas Aplikasi.

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

CARA BERSIH

Pilihan yang lebih baik adalah membuat layanan dan tetap menggunakan logika yang serupa. Pertama buat Layanan baru

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

Dan kemudian tambahkan ke file AndroidManifest

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

Terakhir, Anda dapat menggunakan metode statis dari Layanan Anda MyFirebaseMessagingService.getToken(Context);

YANG TERCEPAT TAPI TIDAK DIGUNAKAN LAGI

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

Ini masih berfungsi saat Anda menggunakan pustaka firebase yang lebih lama dari versi 17.xx

Eliasz Kubala
sumber
6
Tetapi pendekatan kedua hanya berfungsi sampai preferensi bersama dihapus. Bagaimana jika data aplikasi dihapus dan nilai string itu hilang? Android tidak memanggil "onNewtoken ()" karena tidak ada token baru . Tapi lalu bagaimana kita meminta token? Di mana-mana dikatakan "cukup gunakan onNewToken ()" tetapi metode itu hanya berjalan ketika ada token baru . Katakanlah metode itu sudah berjalan, tetapi kami tidak repot-repot menyimpan token. Nanti kita melakukan pengecekan dan melihat bahwa token tersebut belum diset, lalu bagaimana? Bagaimana cara memicu FCM untuk memberi tahu saya token lagi?
JeneralJames
1
Anda dapat menggunakan FirebaseInstanceId.getInstance().getInstanceId()alih-alih FirebaseInstanceId.getInstance().getToken(), lihat jawaban ini
Vadim Kotov
@JeneralJames jika pengguna menghapus data aplikasi, maka onNewTokenakan selalu dipicu, dari dokumentasi di sini firebase.google.com/docs/cloud-messaging/android/…
sarah
26

Tim di balik Firebase Android SDK sedikit mengubah API. Saya telah menerapkan logika "Token to Server" seperti ini:

Dalam contoh saya di FirebaseMessagingService:

public class FirebaseCloudMessagingService extends FirebaseMessagingService {

    ...

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

    ...

}

Perlu diingat bahwa token berlaku untuk setiap perangkat, dan dapat diupdate oleh Firebase terlepas dari logika login Anda. Jadi, jika Anda memiliki fungsi Masuk dan Keluar, Anda harus mempertimbangkan kasus tambahan:

  1. Saat pengguna baru masuk, Anda perlu mengikat token ke pengguna baru (mengirimkannya ke server). Karena token mungkin diperbarui selama sesi pengguna lama dan server tidak mengetahui token pengguna baru.
  2. Saat pengguna keluar, Anda perlu melepaskan token. Karena pengguna seharusnya tidak menerima notifikasi / pesan lagi.

Menggunakan API baru, Anda bisa mendapatkan token seperti ini:

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

Semoga berhasil!

rzaaeeff
sumber
Mencoba untuk mendapatkan nilai di luar OnSuccess memberikan null.
DragonFire
Fungsionalitas login / logout tidak ada hubungannya dengan pesan Push, ini adalah kasus penggunaan bisnis tertentu. Misalnya, Anda mungkin ingin menargetkan pengguna yang keluar dengan beberapa pemberitahuan pemasaran / promosi agar mereka masuk kembali ke aplikasi, dalam hal ini Anda memerlukan token FCM. Tetapi jawabannya benar dalam hal mendapatkan token.
milosmns
@milosmns, Anda benar dalam hal pemberitahuan pemasaran / promo. Masih diperlukan indikasi status token. Solusi sederhananya adalah dengan menyimpan token yang tidak terikat di beberapa jenis tabel riwayat dan kemudian menggunakan token yang lalu tersebut untuk mendorong penggunaan masuk kembali.
rzaaeeff
Hm Saya tidak yakin sebenarnya berapa lama Anda dapat menggunakan kembali token yang sama dan kapan tepatnya itu menjadi tidak valid. Ini perlu diselidiki, karena saya rasa Anda perlu menghapus tabel riwayat / cache / persistensi ini setelah token menjadi tidak valid.
milosmns
@milosmns, di Firebaseland, masa berlaku token tidak akan habis melainkan diperbarui. Saat Anda memicu aktivitas terkait token dengan FCM API, token yang diberikan akan divalidasi. Jika token tidak valid, Anda akan menerima error: MissingRegistration atau error: InvalidRegistration. Anda dapat menemukan lebih banyak kode kesalahan di sini: firebase.google.com/docs/cloud-messaging/…
rzaaeeff
24

Informasi penting.

jika layanan google play macet atau tidak berjalan, maka fcm return token = null

Jika layanan bermain bekerja dengan baik maka FirebaseInstanceId.getInstance().getToken()metode kembalitoken

Log.d("FCMToken", "token "+ FirebaseInstanceId.getInstance().getToken());
Yogesh Rathi
sumber
Ya, Tapi ini sangat sering terjadi
Hoang Duc Tuan
Token di-cache (kemungkinan besar di-mem) setelah diambil sekali. Jadi ini berarti Anda perlu mengambilnya sekali atau meminta Firebase untuk menerbitkan kembali token lain untuk Anda. Lihat di sini untuk cara mengambil stackoverflow
manual.com/a/51630819/2102748
13

Menurut dok

Migrasikan aplikasi klien GCM ke FCM

onTokenRefresh()

hanya Dipanggil jika token InstanceID diperbarui

Jadi itu akan menelepon hanya pada saat pertama kali Anda memasang aplikasi ke perangkat Anda.

Jadi saya sarankan tolong hapus instalan aplikasi Anda secara manual dan coba jalankan lagi

pasti kamu akan mendapatkan TOKEN

Gaurav
sumber
2
tidak menginstal ulang, uninstall secara manual kemudian jalankan proyek,
Gaurav
hapus komentar baris ini String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken);
Gaurav
1
@Gaurav, Bagaimana saya bisa mendapatkan token setelah login kedua? onTokenRefreshtidak memanggil setiap login. bagaimana saya bisa mendapatkan token di layar login saya?
delavega66
3
@ de_la_vega_66, Anda harus menyimpan token Anda pada login pertama
Gaurav
Layanan Anda yang memperluas FirebaseInstanceIdService dan memiliki metode callback onTokenRefresh () HARUS didaftarkan di file Manifes: <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

Coba ini. Mengapa Anda menggunakan RegistrationIntentService?

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

    private void registerToken(String token) {

    }
}
FireUser
sumber
8

Baris ini akan memberi Anda token FCM firebase.

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

Lakukan Log.d untuk mencetaknya ke monitor android.

Alphonsus Chen
sumber
Ini mengembalikan null
Kishan Solanki
7

Daripada ini:

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

Melakukan hal ini:

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

Dan satu hal lagi:

Anda perlu memanggil sendRegistrationToServer()metode yang akan memperbarui token di server, jika Anda mengirim pemberitahuan push dari server.

MEMPERBARUI:

Token Firebase baru dibuat ( onTokenRefresh()dipanggil) ketika:

  • Aplikasi menghapus ID Instance
  • Aplikasi dipulihkan di perangkat baru
  • Pengguna mencopot pemasangan / memasang ulang aplikasi
  • Pengguna menghapus data aplikasi.
aktif sejak 93
sumber
Saya harus menghapus ID Instance FirebaseInstanceId.getInstance (). DeleteInstanceId () tetapi mendapat SERVICE ERROR,
Hardik9850
2
Anda perlu menjalankan FirebaseInstanceId.getInstance().deleteInstanceId()di Thread lain
rockar06
6

Pada saat yang sama, jangan lupa untuk memasukkan ini ke dalam file manifes Anda untuk menerima id token

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

Metode getToken()ini tidak digunakan lagi. Anda bisa menggunakan getInstanceId()sebagai gantinya.

Jika Anda ingin menangani hasil saat meminta instanceId(token), periksa kode ini.

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()));
sNash
sumber
4

Di firebase-messaging:17.1.0FirebaseInstanceIdService dan yang lebih baru tidak digunakan lagi, Anda bisa mendapatkan onNewTokendi FirebaseMessagingServicekelas seperti yang dijelaskan di https://stackoverflow.com/a/51475096/1351469

Tetapi jika Anda ingin mendapatkan token kapan saja, maka sekarang Anda dapat melakukannya seperti ini:

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( this.getActivity(),  new OnSuccessListener<InstanceIdResult>() {
  @Override
  public void onSuccess(InstanceIdResult instanceIdResult) {
    String newToken = instanceIdResult.getToken();
    Log.e("newToken",newToken);
  }
});
jcesarmobile.dll
sumber
Bisakah ini dikembalikan, sehingga fungsi yang sama dapat digunakan di banyak tempat atau kita harus menyalin dan menempel karena firebase bersifat asinkron
DragonFire
3

Jika menggunakan beberapa fungsi autentikasi firebase, Anda dapat mengambil token menggunakan ini:

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

Bekerja dengan baik jika pengguna masuk. getCurrentUser ()

Diego Venâncio
sumber
2

coba ini

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

bagi yang mendarat di sini, sampai sekarang FirebaseInstanceIdServicesudah usang, gunakan saja:

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

dan nyatakan di AndroidManifest

<application... >

<service android:name=".fcm.MyFirebaseMessagingService">
    <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
</application>
pengguna1908375
sumber
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();

            }
        });
pruthwiraj.kadam
sumber
0

The FirebaseInstanceId.getInstance().getInstanceId()adalah usang . Berdasarkan dokumen firebase , Anda dapat mengambil token pendaftaran saat ini menggunakan kode berikut:

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

Anda dapat menggunakan berikut ini di Firebase (FCM) untuk mendapatkan token:

FirebaseInstanceId.getInstance().getToken();
Ahmed Sayed
sumber
2
Metode getToken () tidak digunakan lagi! Jawaban terbaik, sekarang, dari @rzaaeeff.
Damiii
-9
Settings.Secure.getString(getContentResolver(),
                     Settings.Secure.ANDROID_ID);
Saurabh G.
sumber
Kode itu untuk mendapatkan ID android perangkat, Bukan token firebase.
Syed Afeef