Google FCM推送集成及问题排查

一、集成流程概要:

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文件:

Google FCM推送集成及问题排查

Google FCM推送集成及问题排查

分析出问题原因,就好解决问题了,直接在忽略文件中把这两个文件忽略掉就行了。

处理完后经过测试,没有问题了!

总结:

咱们项目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

上一篇:数据库|如何将MySQL完全卸载


下一篇:(VIP-朝夕教育)2021-06-19 .NET高级班 54-.NET Core添加cookie的方式进行授权,鉴权