Firebase (FCM)如何获取令牌

这是我第一次使用 FCM。

我从 Firebase/Quick start-android下载了一个示例并安装了 FCM 快速启动。但是我不能从日志中得到任何令牌甚至在应用程序中击中 日志标记按钮

然后我尝试用 Firebase 控制台发送一条消息,并设置为针对我的应用程序包名称。我收到了来电。

我想知道是否可以使用 FCM? GCM 一切正常。

解决方案:

因为我不是一个 Android 开发者,只是一个后端开发者。所以我需要点时间来解决。在我看来,这个示例应用程序有一些缺陷。

enter image description here

密码:

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

我的 FirebaseInstanceIDService.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.
}
}

在 MainActivity.java 中添加这个。

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

完成以上操作后,您将在 Logcat 获得令牌。但是最后,我找到了一个 方便的方法来获取 it.只需使用调试模式来安装示例应用程序,您可以在第一次安装它时获取令牌。

但我不知道为什么安装的时候不能打印日志。可能跟移动系统有关。

然后为什么我不能得到通知。 已收到 FirebaseMessagingService.onMessageRecected没有呼叫 SendNotification

367241 次浏览

医生说的

将 GCM 客户机应用程序迁移到 FCM

onTokenRefresh()

只有在更新了 InstanceID 令牌时才调用

因此,它只会在第一次调用时,你安装应用程序到您的设备。

所以我建议您手动卸载您的应用程序,并尝试再次运行

你肯定会得到 TOKEN

试试这个。你为什么使用 RegistrationIntentService

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


private void registerToken(String 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]

这样做:

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

还有一件事:

您需要调用 sendRegistrationToServer()方法 如果发送 push,它将更新服务器上的令牌 来自服务器的通知。

更新:

生成新的 Firebase 令牌(调用 onTokenRefresh())时:

  • 应用程序删除实例 ID
  • 应用程序在新设备上恢复
  • 用户卸载/重新安装应用程序
  • 用户清除应用程序数据。

重要信息。

如果谷歌播放服务挂起或不运行, 然后 fcm 返回令牌 = null

如果播放服务工作正常,然后 FirebaseInstanceId.getInstance().getToken()方法返回 token

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

速度最快,有利于原型

快速的解决方案是将它存储在 sharedPrefs 中,并将此逻辑添加到 MainActivity 或扩展 Application 的类中的 onCreate方法中。

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

更干净的路

一个更好的选择是创建一个服务并保持类似的逻辑

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

然后将其添加到 AndroidManifest 文件中

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

最后,您可以使用服务 MyFirebaseMessagingService.getToken(Context);中的静态方法

速度最快,但是不赞成

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

当你使用比17.x. x 版本更老的 Firebase 库时,它仍然可以工作

同时,不要忘记在您的清单文件中包含这个来接收令牌 ID

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

如果正在使用 firebase 的某个 auth 函数,您可以使用以下命令获取令牌:

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

如果用户被记录,则工作正常

这一行应该可以得到 FCM 令牌。

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

执行 Log.d 将其打印到 android 监视器。

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

对于那些在这里登陆的人,到目前为止 FirebaseInstanceIdService已经被废弃了,改用:

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

并在 Android 舱单中声明

<application... >


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

firebase-messaging:17.1.0和更新的 FirebaseInstanceIdService 中不推荐使用,您可以在 FirebaseMessagingService类中获得 onNewToken,正如在 https://stackoverflow.com/a/51475096/1351469中所解释的那样

但是如果你想随时得到令牌,那么现在你可以这样做:

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

完整的解决方案:

Firebase Android SDK 背后的团队稍微改变了一下 API,我实现了“ Token to Server”逻辑如下:

在我的 FirebaseMessagingService 实例中:

public class FirebaseCloudMessagingService extends FirebaseMessagingService {


...


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


...


}

请记住,令牌是每个设备的,并且不管您的登录逻辑如何,它都可以由 Firebase 更新。因此,如果你有登录和注销功能,你必须考虑额外的情况:

  1. 当一个新用户登录时,您需要将令牌绑定到新用户(将其发送到服务器)。因为令牌可能在旧用户的会话期间更新,而服务器不知道新用户的令牌。
  2. 当用户注销时,您需要取消绑定令牌。因为用户不应该再接收通知/消息。

使用新的 API,您可以得到如下令牌:

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

祝你好运!

您可以在 Firebase (FCM)中使用以下命令获取令牌:

FirebaseInstanceId.getInstance().getToken();

试试这个

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

FirebaseInstanceId类及其方法 getInstanceId也不推荐使用。因此必须使用 FirebaseMessaging类,而它是 getToken方法。

FirebaseMessaging.getInstance().getToken().addOnSuccessListener(token -> {
if (!TextUtils.isEmpty(token)) {
Log.d(TAG, "retrieve token successful : " + token);
} else{
Log.w(TAG, "token should not be null...");
}
}).addOnFailureListener(e -> {
//handle e
}).addOnCanceledListener(() -> {
//handle cancel
}).addOnCompleteListener(task -> Log.v(TAG, "This is the token : " + task.getResult()));

不推荐使用 getToken()方法。可以改用 getInstanceId()

如果您希望在请求 instanceId(token)时处理结果,请检查此代码。

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


}
});

FirebaseInstanceId.getInstance().getInstanceId()不赞成。基于 火库文件,您可以使用以下代码检索当前的注册令牌:

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

不推荐使用 FirebaseInstanceId.getInstance () . getInstanceId ()。 现在获取用户 FCM 令牌

 FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(@NonNull Task<String> task) {
if (!task.isSuccessful()) {
System.out.println("--------------------------");
System.out.println(" " + task.getException());
System.out.println("--------------------------");
return;
}


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


// Log
String msg = "GET TOKEN " + token;
System.out.println("--------------------------");
System.out.println(" " + msg);
System.out.println("--------------------------");


}
});

更新日期11-12-2020

当你使用 'com.google.firebase:firebase-messaging:21.0.0'FirebaseInstanceId现在被破坏了

现在我们需要使用 FirebaseInstallations.getInstance().getToken()FirebaseMessaging.getInstance().token

样本代码

FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener {
firebaseToken = it.result!!.token
}


// OR


FirebaseMessaging.getInstance().token.addOnCompleteListener {
if(it.isComplete){
firebaseToken = it.result.toString()
Util.printLog(firebaseToken)
}
}

可以使用此方法获取带有 firebase 的设备令牌

 FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(@NonNull Task<String> task) {
String deviceToken = task.getResult();
}
});

在挂起函数中获取 firebase 令牌的示例

override suspend fun sendTokenToServer() {
try {
 

val token = FirebaseMessaging.getInstance().token.await()
Log.i("TAG", "token " + token)
} catch (exception:Exception) {


}
}

这是在 Activity (2021)中获取 fcm 令牌的最新代码。

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.d(TAG, "fcm token : "+token);
                        

}
});

对于 new Token,只需在 FirebaseMessagingService 扩展类中添加 newToken 方法。

@Override
public void onNewToken(String token) {
super.onNewToken(token);
Log.d(TAG, token);
}

我长话短说,这是唯一没有被否决的方法来获取 Firebase 的令牌:

FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener(task -> {
// get token
String token = task.getResult().getToken();
})

使用以下代码为最新的防火基地版本 -'com.google.firebase:firebase-messaging:22.0.0'

FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(task -> {


if (!task.isSuccessful()) {
//handle token error
return;
}


strAppToken = task.getResult();


});

颤振解决方案:

var token = await FirebaseMessaging.instance.getToken();

如果你正在使用 kotlin 和 co- 常规,然后添加 kotlin 协同常规发挥 图书馆

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:x.x.x'

使用这个简单的方法:

FirebaseMessaging.getInstance().token.await()

如果您正在使用以上“ com.google.firebase: firebase-message: 22.0.0”

以 Kotlin 方式获取 FCM 令牌(武力) :

FirebaseMessaging.getInstance().token.addOnCompleteListener { task: Task<String> ->
if (!task.isSuccessful) {
return@addOnCompleteListener
}


pushToken = task.result
Log.i("PUSH_TOKEN", "pushToken: $pushToken")
}

您可以通过 onNewToken 方法获得令牌(这个类必须实现)

class PushNotificationService: FirebaseMessagingService() {


override fun onNewToken(token: String) {
Log.e("PUSH_TOKEN", "Refreshed firebase token: $token")
}
}

您需要将 推送通知服务添加到 AndroidManifest.xml

<service
android:name=".PushNotificationService"
android:exported="false"
tools:ignore="Instantiatable">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>