Android - 在 react-native 如何解决海内外的推送

1,195 阅读1分钟

一直都是在海外做 react-native 的项目。但是最近项目要兼容国内。因此需要在推送方面进行修改(海外使用 firebase,国内使用友盟)。

网络检测法

检测手机能不能访问 google 就选择不同的方案,但是后来发现这样做太耗时了,而且受到网络影响很大。因此对它进行改造。但是也有好处,就是不用动原生代码,直接在 javascript 端搞就完事了。

google-services 检测法

第一次改造的时候,想到的是我们直接检测手机上是否有 google-services。有的话就直接使用 firebase。

  1. 在 build.gradle 下添加 google-services
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath 'com.google.gms:google-services:4.3.8'
    }
    
  2. 在 app/build.gradle 下添加 google-services 的一些基础库
    dependencies {
        implementation 'com.google.android.gms:play-services-base:17.6.0'
        implementation 'com.google.android.gms:play-services-maps:17.0.1'
        implementation 'com.google.android.gms:play-services-analytics:17.0.0'
    }
    
  3. 代码中导出结果给 javascript
    int res =  GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
    if(res == ConnectionResult.SUCCESS){
        // 支持
    }
    else{
        // 不支持
    }
    

这个方案只是做了一半,就不做下去了。因为发现在代码中判断还是太麻烦了。还不如针对供给应用市场的不同的包来达到目的。这样连判断都不需要了。

渠道法

该法应该是最优解了,但是步骤繁琐。

  1. 在 app/build.gradle 下添加

    android {
        defaultConfig {
            manifestPlaceholders = [appStoreName: "china"]
        }
        flavorDimensions "version"
        productFlavors {
            china {}
            google {}
        }
        productFlavors.all { flavor ->
            flavor.manifestPlaceholders = [appStoreName: name]
        }
    }
    

    修改完这里之后,打包命令就变成了 ./gradlew assemble${productFlavorName}Release, 按照例子来说,我们的打包命令就有两个了: ./gradlew assembleChinaRelease & ./gradlew assembleGoogleRelease

  2. package.json

    "scripts": {
        "android-google": "react-native run-android --variant=googleDebug",
        "android-china": "react-native run-android --variant=chinaDebug",
     },
    
  3. 在 AndroidManifest 添加

    <meta-data
    android:name="appStoreName"
    android:value="${appStoreName}" />
    
  4. 这时候使用 react-native-android-meta-data 就直接在 javascript 中读取 appStoreName 就知道用户在哪里下载的 APP,如果是 google play 就直接使用 firebase 推送即可。

    import AndroidMetaData from 'react-native-android-meta-data'
    const res = await AndroidMetaData.getKey('appStoreName')
    if(res === 'google'){
    }
    else{
    }