Android FCM代币发行

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

我在应用程序的第1版中实现了UrbanAirship。 现在,我在应用程序的第2版中扩展了
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);
}