一、集成流程概要:
1、在Firebase后台注册应用,并下载google-services.json文件,将文件导入到项目中
2、项目中添加依赖:
a、在根级(项目级)Gradle 文件 (build.gradle
) 中添加规则,以纳入 Google 服务 Gradle 插件。此外,请确认您拥有 Google 的 Maven 代码库
buildscript { repositories { // Check that you have the following line (if not, add it): google() // Google's Maven repository } dependencies { // Add the following line: classpath 'com.google.gms:google-services:4.3.4' // Google Services plugin } } allprojects { repositories { // Check that you have the following line (if not, add it): google() // Google's Maven repository // ... } } |
b、使用 Firebase Android BoM 在模块(应用级)Gradle 文件(通常为 app/build.gradle
)中声明 Firebase Cloud Messaging Android 库的依赖项。
// Add the following line: apply plugin: 'com.google.gms.google-services' dependencies { // Import the BoM for the Firebase platform implementation platform( 'com.google.firebase:firebase-bom:26.3.0' ) // Declare the dependencies for the Firebase Cloud Messaging and Analytics libraries // When using the BoM, you don't specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-messaging' implementation 'com.google.firebase:firebase-analytics' } |
3、应用清单文件中添加继承FirebaseMessagingService
的服务
android:name= ".java.FcmService" android:exported= "false" >
"com.google.firebase.MESSAGING_EVENT" />
|
public class FcmService extends FirebaseMessagingService { private String TAG = "FCM---" ; /** * 获取注册令牌token。 * 注册令牌可能会在发生下列情况时更改: * 1、应用在新设备上恢复 * 2、用户卸载/重新安装应用 * 3、用户清除应用数据。 * @param token */ @Override public void onNewToken( @NonNull String token) { super .onNewToken(token); sendRegistrationToServer(token); } /** * 接收消息:以下情况触发不了onMessageReceived方法,消息会在系统通知栏中展示: * 1、当应用在后台(包括应用被杀死和不被杀死)时送达的通知消息 * 2、在后台所接收的同时具备通知和数据载荷的消息。 * @param remoteMessage */ @Override public void onMessageReceived( @NonNull RemoteMessage remoteMessage) { super .onMessageReceived(remoteMessage); //携带的json数据 if (remoteMessage.getData().size() > 0 ) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); } // 通知栏展示的通知内容 if (remoteMessage.getNotification() != null ) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); } } } |
4、在MainActivity的onCreate()中主动获取token:
/** * 获取到最新的FCM token并上报服务器 */ private void uploadFCMToken() { try { int googlePlayServicesAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MainActivity. this ); if (googlePlayServicesAvailable == ConnectionResult.SUCCESS) { FirebaseMessaging.getInstance().getToken() .addOnCompleteListener( new OnCompleteListener() { @Override public void onComplete( @NonNull Task task) { if (task.isSuccessful()) { // Get new FCM registration token String token = task.getResult(); FcmService.sendRegistrationToServer(token); } else { String token = ShareUtil.getString(ShareUtil.FCM_TOKEN, "" ); FcmService.sendRegistrationToServer(token); } } }); } } catch (Exception e) { e.printStackTrace(); // 抛异常提交到bugly CrashReportProxy.postException( "FCM获取token失败:" +TAG, e.getMessage()); } } |
二、遇到的问题:
1、FCM初始化失败且报错:FirebaseInstanceId: Failed to get FIS auth token
java.util.concurrent.ExecutionException: com.google.firebase.installations.FirebaseInstallationsException: Firebase Installations Service is unavailable. Please try again later.
引起以上错误有如下原因:
(1)、肯定会初始化失败的原因
a、部分机型的国产手机不具备Google服务
b、没有链接VPN
(2)、海外手机且VPN链接正常的设备初始化失败问题排查:
a、验证正在测试的所有设备是否具有Play商店和Play服务,并已更新为最新版本。
b、确认Firebase在我的应用程序中设置正确。
c、验证Firebase后台提供的google-services.json与项目中包含的google-services.json是否匹配。
d、验证google-services.json文件中的API密钥,项目ID和应用程序ID是否正确。
e、验证API密钥在Google Cloud Platform中设置限制正常(SHA-1或API限制)或者没有任何限制。
f、确认APK已使用正确的密钥签名-用于调试版本的调试密钥和用于发行版本的应用签名密钥。
排查结果:按照官网的流程进行集成,通过上述问题的排查,并没有发现异常。但是此时测试了四五台设备,只有一台设备能初始化成功。问题陷入了僵局,之后通过查找资料,发现很多人遇到过这种情况,所以尝试以下手段:
1、删除应用中的build文件,然后重新构建项目。
2、修改API密钥在Google Cloud Platform中设置限制,应用限制设置为Android 应用,然后添加添加包名和 SHA-1 签名证书指纹。
3、重新生成新的密钥,之后生成新的google-services.json文件,并导入项目中,之后重新rebuild project。
经过测试,2和3试过后,测试了5台设备,有4台是可以正常获取token的。大部分设备问题解决!
原因分析:经过大量的资料查阅,并没有发现非常准确的原因定位问题,现在根据资料以及现象分析如下原因:
由于咱们项目中还集成了数据分析、Bigquery等内容,这些都可能会对FCM造成影响,导致FCM的密钥失效,而重新构建新的API密钥可以清除这些影响。所以现在基本没问题了。
但是还是有一台获取不了,继续分析原因。
经过反复测试,发现*软件QuickQ有问题,QuickQ有全局模式和智能模式。当选择全局模式时,所有设备都可以收到token,但是当选择智能模式时,有些设备有时会获取不到token。经过和QuickQ客服人员沟通发现:
智能模式:【对于中国地区用户,访问国内网站采用直连方式,国外网站使用加密代理。此项对国外用户无效。此模式需要手动选中应用,如果不选中的话,应用还是走的本地网络】
全局模式:【所有网站都使用加密模式。国内网站可能会出现加载较慢,无法访问情况】
至此:测试的五台设备都可以获取到token,问题解决!
二、资源混淆导致获取不到token
经过上述的处理,理应可以获取到token,但是当使用被资源混淆后的包测试时,token又获取不到了,而且不报任何错误,感觉像是没有添加FCM似的。
问题分析:通过分析资源混淆的原理,它只是把res文件夹下的图片资源、String资源等做混淆。然而FCM只是添加一些依赖和在app文件夹下导入google-services.json文件,在res下并没有直接做任何处理,为什么会导致token获取不到呢?
经过分析FCM初始化的原理,发现应用在打包构建时,会把google-services.json文件中的内容提取成两个String文件,放在res文件夹下面,而初始化FCM时会从这两个String文件中获取信息。然而资源混淆时,刚好把这两个文件的内容也混淆了,导致获取到错误的信息,也就导致初始化失败!以下是google-services.json文件生成的两个string文件:
分析出问题原因,就好解决问题了,直接在忽略文件中把这两个文件忽略掉就行了。
处理完后经过测试,没有问题了!
总结:
咱们项目3.0和3.1版本所有用户都获取不到token,主要原因是由于资源混淆导致的。之后部分手机出现初始化失败且报错,通过设置密钥限制和重新生成新的密钥,大部分设备可以收到token了,最后将*软件QuickQ设置为全局模式。参与测试的所有设备均可正常使用FCM
参考连接:https://*.com/questions/61453640/android-error-when-communicating-with-the-firebase-installations-server-api
https://*.com/questions/60549408/firebase-not-working-com-google-firebase-installations-firebaseinstallationsexce
https://firebase.google.com/support/privacy/init-options