[英]Firebase (FCM) how to get token
It's my first time using FCM.这是我第一次使用 FCM。
I download a sample from firebase/quickstart-android and I install the FCM Quickstart.我从firebase/quickstart-android下载了一个示例,然后安装了 FCM Quickstart。 But I can't get any token from the log even hit the LOG TOKEN button in the app.但我无法从日志中获取任何令牌,甚至点击应用程序中的LOG TOKEN 按钮。
Then I try to send a message with Firebase console and set to target my app package name.然后我尝试使用 Firebase 控制台发送消息并设置为目标我的应用程序包名称。 I got incoming messages.我收到了传入的消息。
I want to know can FCM be used?GCM everything is ok.我想知道FCM可以用吗?GCM一切正常。
Solution:解决方案:
Because I am not an Android developer, just a backend developer.因为我不是安卓开发者,只是后端开发者。 So it takes me some time to solve it.所以我需要一些时间来解决它。 In my opinion, there`re some bugs in the sample app.在我看来,示例应用程序中存在一些错误。
Code:代码:
RegistrationIntentService.java注册意图服务.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 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.
}
}
Add this in the MainActivity.java.在 MainActivity.java 中添加它。
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
After do above,you get the Token in Logcat.完成上述操作后,您就得到了 Logcat 中的 Token。 But finally, I find a convenient way to get it.但最后,我找到了一种方便的方法来获得它。 Just use debug mode to install the sample app and you can get the token when you first time to install it.只需使用调试模式安装示例应用程序,即可在第一次安装时获取令牌。
But I don't know why it can't print the log when I install it.但是不知道为什么安装的时候不能打印日志。 Maybe be related to the mobile system.可能与移动系统有关。
And then why I can't get the Notification.然后为什么我无法收到通知。 FirebaseMessagingService.onMessageReceived did not call sendNotification FirebaseMessagingService.onMessageReceived没有调用sendNotification
The quick solution is to store it in sharedPrefs and add this logic to onCreate
method in your MainActivity or class which is extending Application.快速的解决方案是将其存储在 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 :("));
A better option is to create a service and keep inside a similar logic.更好的选择是创建服务并保持类似的逻辑。 Firstly create new 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");
}
}
And then add it to AndroidManifest file然后将其添加到 AndroidManifest 文件中
<service
android:name=".MyFirebaseMessagingService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Finally, you are able to use a static method from your Service MyFirebaseMessagingService.getToken(Context);
最后,您可以使用服务中的静态方法MyFirebaseMessagingService.getToken(Context);
Log.d("Firebase", "token "+ FirebaseInstanceId.getInstance().getToken());
It's still working when you are using older firebase library than version 17.xx当您使用比 17.xx 版本更旧的 firebase 库时,它仍然有效
The team behind Firebase Android SDK change API a little bit. Firebase Android SDK 背后的团队稍微改变了 API。 I've implemented "Token to Server" logic like this:我已经实现了这样的“令牌到服务器”逻辑:
In my instance of FirebaseMessagingService:在我的 FirebaseMessagingService 实例中:
public class FirebaseCloudMessagingService extends FirebaseMessagingService {
...
@Override
public void onNewToken(String token) {
// sending token to server here
}
...
}
Keep in mind that token is per device, and it can be updated by Firebase regardless of your login logic.请记住,令牌是每个设备的,无论您的登录逻辑如何,它都可以由 Firebase 更新。 So, if you have Login and Logout functionality, you have to consider extra cases:因此,如果您具有登录和注销功能,则必须考虑额外的情况:
Using new API, you can get token like this:使用新的 API,您可以获得这样的令牌:
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String token = instanceIdResult.getToken();
// send it to server
}
});
Good luck!祝你好运!
FirebaseInstanceId
class and it's method getInstanceId
are also deprecated. FirebaseInstanceId
类及其方法getInstanceId
也已弃用。 So you have to use FirebaseMessaging
class and it's getToken
method instead.所以你必须使用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()));
The method getToken()
is deprecated.方法 getToken()
已弃用。You can use getInstanceId()
instead.您可以改用getInstanceId()
。
If you want to handle results when requesting instanceId(token)
, check this code.如果您想在请求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()));
Important information.重要信息。
if google play service hung or not running, then fcm return token =
null
如果 google play 服务挂起或未运行,则 fcm return token =null
If play service working properly then FirebaseInstanceId.getInstance().getToken()
method returns token
如果播放服务正常工作,则FirebaseInstanceId.getInstance().getToken()
方法返回token
Log.d("FCMToken", "token "+ FirebaseInstanceId.getInstance().getToken());
According to doc根据文档
Migrate a GCM client app to FCM 将 GCM 客户端应用程序迁移到 FCM
onTokenRefresh()
only Called if InstanceID token is updated仅在更新 InstanceID 令牌时调用
So it will call only at first time when you install an app to your device.因此,它只会在您将应用程序安装到您的设备时第一次调用。
So I suggest please uninstall your app manually and try to run again所以我建议请手动卸载您的应用程序并尝试再次运行
definitely you will get TOKEN你肯定会得到TOKEN
Try this.尝试这个。 Why are you using RegistrationIntentService
?你为什么使用RegistrationIntentService
?
public class FirebaseInstanceIDService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
registerToken(token);
}
private void registerToken(String token) {
}
}
This line should get you the firebase FCM token.此行应该为您提供 firebase FCM 令牌。
String token = FirebaseInstanceId.getInstance().getToken();
Log.d("MYTAG", "This is your Firebase token" + token);
Do Log.d to print it out to the android monitor.执行 Log.d 将其打印到 android 监视器。
If you are using above 'com.google.firebase:firebase-messaging:22.0.0'如果您使用上面的 'com.google.firebase:firebase-messaging:22.0.0'
Get FCM Token (Force) with Kotlin way:用 Kotlin 方式获取 FCM Token (Force):
FirebaseMessaging.getInstance().token.addOnCompleteListener { task: Task<String> ->
if (!task.isSuccessful) {
return@addOnCompleteListener
}
pushToken = task.result
Log.i("PUSH_TOKEN", "pushToken: $pushToken")
}
And you can get token via onNewToken method.您可以通过 onNewToken 方法获取令牌。 (This class must be implemented) (这个类必须实现)
class PushNotificationService: FirebaseMessagingService() {
override fun onNewToken(token: String) {
Log.e("PUSH_TOKEN", "Refreshed firebase token: $token")
}
}
You need add PushNotificationService to AndroidManifest.xml您需要将PushNotificationService添加到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>
Instead of this:而不是这个:
// [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]
Do this:做这个:
// [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]
And one more thing:还有一件事情:
You need to call
sendRegistrationToServer()
method which will update token on server, if you are sending push notifications from server.如果您从服务器发送推送通知,您需要调用sendRegistrationToServer()
方法来更新服务器上的令牌。
UPDATE:更新:
New Firebase token is generated ( onTokenRefresh()
is called) when:在以下情况下会生成新的 Firebase 令牌( onTokenRefresh()
):
At the same time don not forget to include this in your manifest file to receive token id同时不要忘记将其包含在您的清单文件中以接收令牌 ID
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
The FirebaseInstanceId.getInstance().getInstanceId()
is deprecated . FirebaseInstanceId.getInstance().getInstanceId()
已弃用。 Based on firebase document , you can retrieve the current registration token using following code:基于firebase 文档,您可以使用以下代码检索当前注册令牌:
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();
}
});
UPDATE 11-12-2020 2020 年 11 月 12 日更新
When you use 'com.google.firebase:firebase-messaging:21.0.0'
is FirebaseInstanceId
is depreacted now当您使用'com.google.firebase:firebase-messaging:21.0.0'
, FirebaseInstanceId
现在已被弃用
Now we need to use FirebaseInstallations.getInstance().getToken()
and FirebaseMessaging.getInstance().token
现在我们需要使用FirebaseInstallations.getInstance().getToken()
和FirebaseMessaging.getInstance().token
SAMPLE CODE示例代码
FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener {
firebaseToken = it.result!!.token
}
// OR
FirebaseMessaging.getInstance().token.addOnCompleteListener {
if(it.isComplete){
firebaseToken = it.result.toString()
Util.printLog(firebaseToken)
}
}
You can use this method to get device token with firebase您可以使用此方法通过 firebase 获取设备令牌
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(@NonNull Task<String> task) {
String deviceToken = task.getResult();
}
});
In firebase-messaging:17.1.0
and newer the FirebaseInstanceIdService is deprecated, you can get the onNewToken
on the FirebaseMessagingService
class as explained on https://stackoverflow.com/a/51475096/1351469在firebase-messaging:17.1.0
和更新版本中,不推荐使用 FirebaseInstanceIdService,您可以按照https://stackoverflow.com/a/51475096/1351469中的说明在FirebaseMessagingService
类上获取onNewToken
But if you want to just get the token any time, then now you can do it like this:但是,如果您想随时获取令牌,那么现在您可以这样做:
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( this.getActivity(), new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken",newToken);
}
});
If you are using kotlin and co-routine then add kotlin coroutine play library如果你使用的是 kotlin 和协程然后添加 kotlin 协程播放库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:x.x.x'
use this simple method:使用这个简单的方法:
FirebaseMessaging.getInstance().token.await()
If are using some auth function of firebase, you can take token using this:如果正在使用 firebase 的某些身份验证功能,您可以使用以下方式获取令牌:
//------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();
// ...
}
}
});
Work well if user are logged.如果用户已登录,则工作良好。 getCurrentUser()获取当前用户()
This the latest code to get fcm token in Activity (2021).这是在 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);
}
});
For new Token just add the newToken Method in FirebaseMessagingService extended class.对于新 Token,只需在 FirebaseMessagingService 扩展类中添加 newToken 方法。
@Override
public void onNewToken(String token) {
super.onNewToken(token);
Log.d(TAG, token);
}
try this尝试这个
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener(OnSuccessListener<InstanceIdResult> { instanceIdResult ->
fcm_token = instanceIdResult.token}
for those who land here, up to now FirebaseInstanceIdService
is deprecated now, use instead:对于那些登陆这里的人,到目前为止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);
}
}
and declare in AndroidManifest并在 AndroidManifest 中声明
<application... >
<service android:name=".fcm.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
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();
}
});
Example to get firebase token inside suspend function在挂起函数中获取 firebase 令牌的示例
override suspend fun sendTokenToServer() {
try {
val token = FirebaseMessaging.getInstance().token.await()
Log.i("TAG", "token " + token)
} catch (exception:Exception) {
}
}
I'll make this short.我会把这个简短的。 This is the only non-deprecated way to retrieve the Firebase's token:这是检索 Firebase 令牌的唯一不被弃用的方法:
FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener(task -> {
// get token
String token = task.getResult().getToken();
})
Use below code for latest firebase version - 'com.google.firebase:firebase-messaging:22.0.0'
使用以下代码获取最新的 firebase 版本 - 'com.google.firebase:firebase-messaging:22.0.0'
FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
//handle token error
return;
}
strAppToken = task.getResult();
});
您可以在 Firebase (FCM) 中使用以下内容来获取令牌:
FirebaseInstanceId.getInstance().getToken();
FirebaseInstanceId.getInstance().getInstanceId() deprecated. FirebaseInstanceId.getInstance().getInstanceId() 已弃用。 Now get user FCM token现在获取用户 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("--------------------------");
}
});
var token = await FirebaseMessaging.instance.getToken();
Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.