Android FCM代币发行
我在应用程序的第1版中实现了UrbanAirship。 现在,我在应用程序的第2版中扩展了Android FCM代币发行,android,firebase-cloud-messaging,Android,Firebase Cloud Messaging,我在应用程序的第1版中实现了UrbanAirship。 现在,我在应用程序的第2版中扩展了FirebaseMessagingService。 我在onNewToken()中没有收到能够将令牌发送到我的服务器的调用。 我的样板代码看起来像 AndroidManifest.xml <service android:name=".services.fcm.PushMessageReceiver" android:enabled="true" a
FirebaseMessagingService
。
我在onNewToken()
中没有收到能够将令牌发送到我的服务器的调用。
我的样板代码看起来像
AndroidManifest.xml
<service
android:name=".services.fcm.PushMessageReceiver"
android:enabled="true"
android:exported="true"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
意见:
1) 对于正在更新的应用程序,永远不会调用onNewToken
2) 新安装获得令牌
3) 在我添加了对FirebaseInstanceId.getInstance().deleteInstanceId()的调用之后
OnComplete也不会被调用
4) 在真实手机(不是模拟器)上调用getToken(senderId,“FCM”)
总是会导致
java.io.IOException: TOO_MANY_REGISTRATIONS
at com.google.firebase.iid.zzr.zza(Unknown Source:66)
at com.google.firebase.iid.zzr.zza(Unknown Source:79)
at com.google.firebase.iid.zzu.then(Unknown Source:4)
at com.google.android.gms.tasks.zzd.run(Unknown Source:5)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
如何修正观测值1。是不是因为代币已经发送到UrbanAirship,onNewToken没有被调用?
仅供参考,getToken是在serviceonCreate()方法中调用的
您可以通过以下方式获得fcm代币:-
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (task.isSuccessful()) {
String firebaseToken = task.getResult().getToken();
} else {
getFirebaseToken();
}
}
});
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
字符串firebaseToken=task.getResult().getToken();
}否则{
getFirebaseToken();
}
}
});
如果未调用onNewToken(),则可以。您可以获得firebase为您的设备制作的最新令牌。onNewToken()在特定场合被调用
在以下情况下,注册令牌可能会更改:
-应用程序删除实例ID
-应用程序已在新设备上还原
-用户卸载/重新安装应用程序
-用户清除应用程序数据
请务必阅读firebase文档:
对于第二个查询,deleteInstanceId是一个阻塞调用,因此必须在后台线程中执行。像这样,
new Thread(new Runnable() {
@Override
public void run() {
try {
FirebaseInstanceId.getInstance().deleteInstanceId();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
有一段时间onTokenRefresh()方法调用会有一些延迟,当新安装发生时,它会生成令牌,它的行为如何,因为我们需要实现如下功能来克服这些问题,同时维护新用户登录
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private String TAG = getClass().getName();
public static final String TOKEN_BROADCAST = "myfcmtokenbroadcast";
@Override
public void onTokenRefresh() {
//For registration of token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//To displaying token on logcat
Log.d("TOKEN: ", refreshedToken);
//calling the method store token and passing token
getApplicationContext().sendBroadcast(new Intent(TOKEN_BROADCAST));
storeToken(refreshedToken);
}
private void storeToken(String token) {
//we will save the token in sharedpreferences later
SharedPrefManager.getInstance(getApplicationContext()).saveDeviceToken(token);
}
}
在MainActivity类中的onCreate方法中,调用此方法
private void registerFCMToken(){
registerReceiver(broadcastReceiver, new IntentFilter(MyFirebaseInstanceIDService.TOKEN_BROADCAST));
final boolean isRegisterFcm = preferences.getBoolean("IS_REGISTER_FCM", false);
// FCM token Register when onTokenRefresh method call
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String fcmToken = SharedPrefManager.getInstance(MainActivity.this).getDeviceToken();
if(!isRegisterFcm) {
RegisterFcmTokenRequest request = new RegisterFcmTokenRequest();
request.setFcmtoken(fcmToken);
performRegisterFcmRequest(request);
}
}
};
// FCM token Register when new user Login
if(SharedPrefManager.getInstance(this).getDeviceToken() != null && !isRegisterFcm) {
String fcmToken = SharedPrefManager.getInstance(MainActivity.this).getDeviceToken();
RegisterFcmTokenRequest request = new RegisterFcmTokenRequest();
request.setFcmtoken(fcmToken);
performRegisterFcmRequest(request);
}
}
在onDestroy方法中
unregisterReceiver(broadcastReceiver);
此类维护FCM令牌的Shredpreferance
public class SharedPrefManager {
private static final String SHARED_PREF_NAME = "FCMSharedPref";
private static final String TAG_TOKEN = "tagtoken";
private static SharedPrefManager mInstance;
private static Context mCtx;
private SharedPrefManager(Context context) {
mCtx = context;
}
public static synchronized SharedPrefManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new SharedPrefManager(context);
}
return mInstance;
}
//this method will save the device token to shared preferences
public boolean saveDeviceToken(String token){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(TAG_TOKEN, token);
editor.apply();
return true;
}
//this method will fetch the device token from shared preferences
public String getDeviceToken(){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(TAG_TOKEN, null);
}
}您能解释一下这个错误是什么吗?FCN令牌问题就是这个错误,但在我引入deleteInstanceId()之后,我的onComplete没有被调用这是否意味着我应该删除它?你不需要为fcm令牌创建一个类你可以调用这个方法并获取fcm令牌我也做了你所做的,我也面临这个问题,然后我删除了这个类并调用这个方法并获取fcm令牌“你可以获取firebase已经为你的设备制作的最新令牌。”你能分享一个具体的方法吗?我想说的是你可以使用这个,字符串token=FirebaseInstanceId.getInstance().getToken();好的,我已经在电话上这样做了,我在com.google.firebase.iid.zzr.zza(未知源代码:66)在com.google.firebase.iid.zzr.zza(未知源代码:79)在com.google.firebase.iid.zzu.then(未知源代码:4)在com.google.android.gms.tasks.zzd.run(未知源代码:5)上得到了太多的注册onTokenRefresh是一种不推荐使用的方法
unregisterReceiver(broadcastReceiver);
public class SharedPrefManager {
private static final String SHARED_PREF_NAME = "FCMSharedPref";
private static final String TAG_TOKEN = "tagtoken";
private static SharedPrefManager mInstance;
private static Context mCtx;
private SharedPrefManager(Context context) {
mCtx = context;
}
public static synchronized SharedPrefManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new SharedPrefManager(context);
}
return mInstance;
}
//this method will save the device token to shared preferences
public boolean saveDeviceToken(String token){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(TAG_TOKEN, token);
editor.apply();
return true;
}
//this method will fetch the device token from shared preferences
public String getDeviceToken(){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(TAG_TOKEN, null);
}