Closed maggialejandro-rp closed 4 years ago
Strange. One thing I see is that you've got hermes enabled. I'd disable that there was a bug logged here where hermes was taking valid react-native-firebase code and not running it correctly. That's pretty vague, but it is also a variable you can try with at least one reported failure in your config.
That said, if it has no affect then this should either crash all the time if there was an integration failure, or if it only crashes sometimes then it might be due to google splitting things wrong, or ??. Is there any way you can examine the APK delivered by google to those devices?
Hi @mikehardy This is the content of the app that uses the device with more crashes
extracting: lib/armeabi-v7a/libabecs.so
extracting: lib/armeabi-v7a/libabecsandroid.so
extracting: lib/armeabi-v7a/libc++_shared.so
extracting: lib/armeabi-v7a/libcrashlytics.so
extracting: lib/armeabi-v7a/libfb.so
extracting: lib/armeabi-v7a/libfolly_futures.so
extracting: lib/armeabi-v7a/libfolly_json.so
extracting: lib/armeabi-v7a/libglog.so
extracting: lib/armeabi-v7a/libglog_init.so
extracting: lib/armeabi-v7a/libhermes-executor-debug.so
extracting: lib/armeabi-v7a/libhermes-executor-release.so
extracting: lib/armeabi-v7a/libhermes-inspector.so
extracting: lib/armeabi-v7a/libhermes.so
extracting: lib/armeabi-v7a/libimagepipeline.so
extracting: lib/armeabi-v7a/libjscexecutor.so
extracting: lib/armeabi-v7a/libjsijniprofiler.so
extracting: lib/armeabi-v7a/libjsinspector.so
extracting: lib/armeabi-v7a/libnative-filters.so
extracting: lib/armeabi-v7a/libnative-imagetranscoder.so
extracting: lib/armeabi-v7a/libreactnativeblob.so
extracting: lib/armeabi-v7a/libreactnativejni.so
extracting: lib/armeabi-v7a/libyoga.so
I'm going to investigate what you mention about Hermes config, thanks
Yeah - strange. libcrashlytics.so is there no problem :thinking:
You could turn off NDK reporting for crashlytics via the firebase json config file that RNFB has, here's the option for it: https://invertase.io/oss/react-native-firebase/v6/app/reference/firebasejsonconfig#crashlytics_ndk_enabled
Obviously it doesn't fix the underlying issue but should at least stop the crashes. I'm not particularly sure why this would be crashing, hermes might be something causing an issue as it also uses a ndk library but there's not much information in the stack trace, it could even be an issue with the specific version of crashlytics you are using.
Thanks @Salakar, disabling crashlytics_ndk_enabled
stopped the crashes
You can close this if you want.
Issue
Crashing on these devices:
Stacktrace:
Project Files
package.json
:Android
Click To Expand
#### Have you converted to AndroidX? - [x] my application is an AndroidX application - [x] I am using `android.enableJetifier=true` in gradle.properties - [ ] I am using the NPM package `jetifier` for react-native compatibility #### `android/build.gradle`: ```groovy buildscript { repositories { mavenLocal() google() jcenter() maven { url 'https://maven.fabric.io/public' } } dependencies { classpath('com.android.tools.build:gradle:3.5.0') { exclude module: 'proguard-gradle' } classpath('net.sf.proguard:proguard-gradle:5.2.1') { force = true } classpath 'de.undercouch:gradle-download-task:4.0.0' classpath 'com.google.gms:google-services:4.3.2' classpath 'io.fabric.tools:gradle:1.31.1' classpath 'com.google.firebase:perf-plugin:1.3.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } project.ext.versionCode = project.versionCodeString.toInteger() project.ext.compileSdkVersion = project.compileSdkVersionString.toInteger() project.ext.buildToolsVersion = project.buildToolsVersion project.ext.minSdkVersion = project.minSdkVersionString.toInteger() project.ext.targetSdkVersion = project.targetSdkVersionString.toInteger() project.ext.googlePlayServicesAuthVersion = project.googlePlayServicesAuthVersion subprojects { group = 'com.recarga.android' repositories { mavenLocal() google() jcenter() maven { url "https://maven.google.com" } mavenCentral() maven { url "https://repo.leanplum.com/" } maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url("$rootDir/../node_modules/react-native/android") } maven { // Android JSC is installed from npm url("$rootDir/../node_modules/jsc-android/dist") } google() jcenter() maven { url 'https://jitpack.io' } } } ``` #### `android/app/build.gradle`: ```groovy description = 'app' def safeExtGet(prop, fallback) { rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback } buildscript { repositories { google() jcenter() mavenLocal() } dependencies { if (!getGradle().getStartParameter().getTaskRequests().toString().matches(".*Debug.*")){ println("Enabling New Relic") classpath 'com.newrelic.agent.android:agent-gradle-plugin:5.24.0' } //classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2' } } apply plugin: 'com.android.application' if (!getGradle().getStartParameter().getTaskRequests().toString().matches(".*Debug.*")){ apply plugin: 'newrelic' apply plugin: 'io.fabric' crashlytics { enableNdk true } apply plugin: 'com.google.firebase.firebase-perf' } project.ext.react = [ entryFile: "index.js", enableHermes: true, // clean and rebuild if changing bundleInQa: true, bundleInRc: true, bundleInRelease: true, bundleInBuild: true, devDisabledInQa: true, devDisabledInRc: true, devDisabledInRelease: true, devDisabledInBuild: true, ] apply from: "../../node_modules/react-native/react.gradle" apply from: "../../node_modules/react-native-code-push/android/codepush.gradle" apply plugin: 'de.undercouch.download' //apply plugin: 'com.getkeepsafe.dexcount' import de.undercouch.gradle.tasks.download.Download import com.android.build.OutputFile /** * The preferred build flavor of JavaScriptCore. * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ def jscFlavor = 'org.webkit:android-jsc:+' /** * Whether to enable the Hermes VM. * * This should be set on project.ext.react and mirrored here. If it is not set * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode * and the benefits of using Hermes will therefore be sharply reduced. */ def enableHermes = project.ext.react.get("enableHermes", false); android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { targetSdkVersion rootProject.ext.targetSdkVersion minSdkVersion rootProject.ext.minSdkVersion versionName project.version versionCode ((rootProject.ext.minSdkVersion * 100000) + rootProject.ext.versionCode) applicationId "com.recarga.recarga" testApplicationId "com.recarga.android.test" buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L" missingDimensionStrategy 'react-native-camera', 'general' // Optional: Specify the language(s) your app supports. resConfigs "en", "pt", "pt_BR" ndk { abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } } signingConfigs { release { storeFile file(project.hasProperty("sign.keystore") ? project.property("sign.keystore") : System.getenv("sign_keystore")) storePassword project.hasProperty("sign.storepass") ? project.property("sign.storepass") : System.getenv("sign_storepass") keyAlias project.hasProperty("sign.alias") ? project.property("sign.alias") : System.getenv("sign_alias") keyPassword project.hasProperty("sign.keypass") ? project.property("sign.keypass") : System.getenv("sign_keypass") } } sourceSets { androidTest { manifest.srcFile file('../tests/AndroidManifest.xml') java.srcDirs = ['../tests/src'] resources.srcDirs = ['../tests/src'] res.srcDirs = ['../tests/res'] assets.srcDirs = ['../tests/assets'] } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } bundle { language { enableSplit = false } density { enableSplit = true } abi { enableSplit = true } } buildTypes { debug { buildConfigField "boolean", "RELEASE", "false" buildConfigField "String", "PERSISTENT_KID", "null" // versionNameSuffix "-dev" multiDexEnabled true manifestPlaceholders = [gcmPermissionRequired: ""] // "" => let the GCM BroadcastReceiver accept Intents from 'adb shell am broadcast' } qa { buildConfigField "boolean", "RELEASE", "false" buildConfigField "String", "PERSISTENT_KID", "null" // versionNameSuffix "-qa" // debuggable true minifyEnabled true shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt' signingConfig signingConfigs.release multiDexEnabled true manifestPlaceholders = [gcmPermissionRequired: ""] // "" => let the GCM BroadcastReceiver accept Intents from 'adb shell am broadcast' matchingFallbacks = ['release'] } build { buildConfigField "boolean", "RELEASE", "false" buildConfigField "String", "PERSISTENT_KID", "null" versionNameSuffix "-build" // debuggable true minifyEnabled true shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt' signingConfig signingConfigs.release multiDexEnabled true manifestPlaceholders = [gcmPermissionRequired: ""] // "" => let the GCM BroadcastReceiver accept Intents from 'adb shell am broadcast' matchingFallbacks = ['release'] } rc { buildConfigField "boolean", "RELEASE", "false" buildConfigField "String", "PERSISTENT_KID", "null" // versionNameSuffix "-rc" minifyEnabled true shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt' signingConfig signingConfigs.release multiDexEnabled true manifestPlaceholders = [gcmPermissionRequired: ""] // "" => let the GCM BroadcastReceiver accept Intents from 'adb shell am broadcast' matchingFallbacks = ['release'] } release { buildConfigField "boolean", "RELEASE", "true" buildConfigField "String", "PERSISTENT_KID", "null" buildConfigField "String", "TEST_USER_EMAIL", "null" buildConfigField "String", "TEST_USER_PASSWORD", "null" minifyEnabled true shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt' signingConfig signingConfigs.release multiDexEnabled true manifestPlaceholders = [gcmPermissionRequired: "com.google.android.c2dm.permission.SEND"] } } dexOptions { javaMaxHeapSize "4g" } lintOptions { checkReleaseBuilds true //disable 'MissingTranslation' // Or, if you prefer, you can continue to check for errors in release builds, // but continue the build even when errors are found: abortOnError false } compileOptions.encoding = 'utf-8' configurations.all { resolutionStrategy { force "com.facebook.soloader:soloader:0.8.0" } resolutionStrategy.eachDependency { DependencyResolveDetails details -> def requested = details.requested if (requested.group == 'com.android.support' && requested.name != 'multidex') { details.useVersion "${rootProject.ext.supportLibVersion}" } } } packagingOptions { exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/notice.txt' exclude 'META-INF/license.txt' exclude 'META-INF/dependencies.txt' exclude 'META-INF/LGPL2.1' exclude 'org/bouncycastle/x509/CertPathReviewerMessages_de.properties' pickFirst 'org/bouncycastle/x509/CertPathReviewerMessages.properties' // pickFirst '**/armeabi-v7a/libc++_shared.so' // pickFirst '**/x86/libc++_shared.so' // pickFirst '**/arm64-v8a/libc++_shared.so' // pickFirst '**/x86_64/libc++_shared.so' // pickFirst '**/x86/libjsc.so' // pickFirst '**/armeabi-v7a/libjsc.so' } } repositories { flatDir { dirs 'libs' dirs '../common/lib/libs' } jcenter() } def supportLibVersion = project.supportLibVersion dependencies { implementation 'com.google.android.material:material:1.0.0' implementation 'org.jdeferred:jdeferred-android-aar:1.2.3' implementation 'javax.inject:javax.inject:1' implementation 'com.google:volley:6.0.1_r55' implementation 'com.facebook.react:react-native:+' implementation (project(':react-native-code-push')) { exclude group: 'net.minidev', module: 'json-smart' } implementation (project(':react-native-mpos-native')) { exclude module: 'mpos-android' exclude group: 'br.com.vivareal', module: 'cuid-android' } implementation project(':react-native-ble-manager') if (enableHermes) { def hermesPath = "../../node_modules/hermes-engine/android/"; debugImplementation files(hermesPath + "hermes-debug.aar") qaImplementation files(hermesPath + "hermes-release.aar") rcImplementation files(hermesPath + "hermes-release.aar") buildImplementation files(hermesPath + "hermes-release.aar") releaseImplementation files(hermesPath + "hermes-release.aar") } else { implementation jscFlavor } implementation 'androidx.core:core:' + safeExtGet('androidXVersion', '1.1.0'); implementation 'androidx.appcompat:appcompat:' + safeExtGet('androidXVersion', '1.1.0'); implementation 'androidx.annotation:annotation:' + safeExtGet('androidXVersion', '1.1.0'); implementation project(':fnbox-android') implementation project(':recarga-payments-android') implementation 'com.leanplum:leanplum-fcm:5.3.1' implementation 'com.leanplum:leanplum-location:5.3.1' implementation('com.facebook.android:account-kit-sdk:' + accountKitSdkVersion) { exclude group: 'com.google.android.gms', module: 'play-services-auth-api-phone' exclude group: 'com.google.android.gms', module: 'play-services-auth' } implementation 'com.googlecode.libphonenumber:libphonenumber:8.+' annotationProcessor 'com.squareup.dagger:dagger-compiler:1.2.5' implementation 'com.squareup.dagger:dagger:1.2.5' implementation 'com.path:android-priority-jobqueue:1.1.2@jar' implementation 'com.appsflyer:af-android-sdk:4.10.3' implementation 'com.android.installreferrer:installreferrer:1.0' implementation 'com.newrelic.agent.android:android-agent:5.24.0' implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar' implementation 'br.com.clearsale.device:clearsaledevice:20160201' implementation 'com.helpshift:android-helpshift-aar:7.6.3' implementation 'net.minidev:json-smart:2.3' implementation('com.google.api-client:google-api-client:1.20.0') { exclude module: "httpclient" exclude module: "guava-jdk5" } implementation('com.google.android.gms:play-services-location:' + safeExtGet('googlePlayServicesLocationVersion', '17.0.0')) { exclude group: 'com.google.android.gms', module: 'play-services-maps' } implementation 'com.google.android.gms:play-services-safetynet:' + safeExtGet('googlePlayServicesSafetynetVersion', '17.0.0'); implementation 'com.google.android.gms:play-services-tagmanager:' + safeExtGet('googlePlayServicesTagmanagerVersion', '17.0.0'); implementation 'com.google.android.gms:play-services-auth:' + safeExtGet('googlePlayServicesAuthVersion', '17.0.0') implementation 'com.google.firebase:firebase-core:' + safeExtGet('firebaseVersion', '17.2.0') implementation 'com.google.firebase:firebase-messaging:' + safeExtGet('firebaseMessagingVersion', '20.0.0') implementation 'com.crashlytics.sdk.android:crashlytics:' + safeExtGet('firebaseCrashlyticsVersion', '2.10.1') implementation 'com.facebook.android:facebook-android-sdk:' + safeExtGet('facebookSdkVersion', '5.+') implementation('com.amplitude:android-sdk:2.12.0') { exclude group: 'com.squareup.okhttp3', module: 'okhttp' } implementation 'me.leolin:ShortcutBadger:1.1.22@aar' implementation('com.siftscience:sift-android:0.10.4') { exclude group: 'com.google.android.gms', module: 'play-services-location' } implementation 'com.squareup.okhttp3:okhttp:3.12.1' implementation ':mpos-android:20190219@aar' implementation ':mpos-android-native:20190219' implementation 'br.com.vivareal:cuid-android:0.1.1@aar' implementation 'com.fasterxml.jackson.core:jackson-core:2.9.1' //2.1.3 implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.1' //2.1.3 implementation "com.adyen.checkout:3ds2:3.4.1" } def countryCodes = [['code':'BR','lang':'pt'], // ['code':'AR','lang':'es'], //['code':'CL','lang':'es'], //['code':'CO','lang':'es'], //['code':'ES','lang':'es'], //['code':'MX','lang':'es'], // ['code':'US','lang':'en'] ]; countryCodes.each { Map country ->
tasks.create(name: "downloadIndexedContextFiles_$country.code", type: Download) {
header("Accept-Language", "$country.lang")
header("Cache-Control", "no-cache")
src(getContexts("https://api.recarga.com", "$country.code"))
new File(rootDir, "app/src/main/assets/prefetched/contexts/$country.code").mkdirs()
dest new File(rootDir, "app/src/main/assets/prefetched/contexts/$country.code")
overwrite true
}
}
def getContexts(apiBaseUrl, countryCode) {
if (countryCode == 'BR') {
return [
"$apiBaseUrl/api/0.1/contexts/$countryCode/index",
"$apiBaseUrl/api/0.1/contexts/$countryCode/operators",
"$apiBaseUrl/api/0.1/contexts/$countryCode/tests",
"$apiBaseUrl/api/0.1/contexts/$countryCode/general",
"$apiBaseUrl/api/0.1/contexts/$countryCode/messages",
"$apiBaseUrl/api/0.1/contexts/$countryCode/offline-payment-options",
"$apiBaseUrl/api/0.1/contexts/$countryCode/shopping"
];
} else {
return [
"$apiBaseUrl/api/0.1/contexts/$countryCode/index",
"$apiBaseUrl/api/0.1/contexts/$countryCode/operators",
"$apiBaseUrl/api/0.1/contexts/$countryCode/tests",
"$apiBaseUrl/api/0.1/contexts/$countryCode/general",
"$apiBaseUrl/api/0.1/contexts/$countryCode/messages",
"$apiBaseUrl/api/0.1/contexts/$countryCode/shopping"
];
}
}
task getCountries {
doFirst {
countryCodes.each { Map country ->
tasks."downloadIndexedContextFiles_$country.code".download();
}
}
}
android.applicationVariants.all { variant ->
if (variant.buildType.name != 'debug') {
variant.generateBuildConfig.dependsOn(tasks.getCountries)
}
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply plugin: 'com.google.gms.google-services'
googleServices {
disableVersionCheck = true
}
```
#### `android/settings.gradle`:
```groovy
rootProject.name = 'recarga-android'
include ':react-native-mpos-native'
project(':react-native-mpos-native').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mpos-native/android')
include ':react-native-ble-manager'
project(':react-native-ble-manager').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-ble-manager/android')
include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':fnbox-android'
project(':fnbox-android').projectDir = "$rootDir/common" as File
include ':recarga-payments-android'
project(':recarga-payments-android').projectDir = "$rootDir/payments" as File
include ':app'
project(':app').projectDir = "$rootDir/app" as File
```
#### `MainApplication.java`:
```java
package com.recarga.recarga;
import android.app.Activity;
import android.app.Application;
import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.core.app.NotificationCompat;
import androidx.appcompat.app.AppCompatDelegate;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.DiskBasedCache;
import com.facebook.react.ReactApplication;
import com.facebook.react.PackageList;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import com.fnbox.android.cache.CachedRequestService;
import com.fnbox.android.cache.PromiseRequestQueue;
import com.fnbox.android.objectstore.CachedObjectStore;
import com.fnbox.android.services.RequestHeadersInjector;
import com.fnbox.android.util.Injector;
import com.leanplum.Leanplum;
import com.leanplum.LeanplumActivityHelper;
import com.leanplum.LeanplumPushNotificationCustomizer;
import com.leanplum.LeanplumPushService;
import com.leanplum.LeanplumResources;
import com.leanplum.annotations.Parser;
import com.microsoft.codepush.react.CodePush;
import com.microsoft.codepush.react.ReactInstanceHolder;
import com.recarga.recarga.activity.WalkthroughActivity;
import com.recarga.recarga.facebook.FacebookHelper;
import com.recarga.recarga.notification.RegistrationIntentService;
import com.recarga.recarga.react.RecargaPackage;
import com.recarga.recarga.services.AuthenticationService;
import com.recarga.recarga.services.ContactsService;
import com.recarga.recarga.services.ContextService;
import com.recarga.recarga.services.DataSyncService;
import com.recarga.recarga.services.ErrorService;
import com.recarga.recarga.services.NotificationService;
import com.recarga.recarga.services.PreferencesService;
import com.recarga.recarga.services.RouterService;
import com.recarga.recarga.services.ShareService;
import com.recarga.recarga.services.TrackingService;
import com.recarga.recarga.services.UserService;
import com.recarga.recarga.services.events.RecargaEventsService;
import com.recarga.recarga.services.ssc.SafetyNetCollector;
import com.recarga.recarga.util.HelpshiftWrapper;
import com.recarga.recarga.util.WebkitCookieManagerProxy;
import org.jdeferred.android.AndroidDeferredManager;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
import javax.inject.Named;
import dagger.ObjectGraph;
public class MainApplication extends Application implements Injector, ReactApplication {
private static MainApplication instance;
private ObjectGraph graph;
RecargaHolder recarga;
private Resources mResources;
public static String sDefSystemLanguage;
private final Object lockRegistration = new Object();
private Context tmpContext;
public MainApplication(Context tmpContext) {
super();
this.tmpContext = tmpContext;
setInstance(this);
}
public MainApplication() {
super();
setInstance(this);
}
private static void setInstance(MainApplication instance) {
if (MainApplication.instance != null) {
if (instance.recarga == null) {
instance.recarga = MainApplication.instance.recarga;
}
if (instance.graph == null) {
instance.graph = MainApplication.instance.graph;
}
}
MainApplication.instance = instance;
if (instance.recarga != null && instance.recarga.applicationModule != null && instance.getBaseContext() != null
&& instance.getApplicationContext() != null) {
instance.recarga.applicationModule.setApplication(instance);
instance.tmpContext = null;
}
}
public void inject(Object object) {
inject(object, ApplicationModule.class);
}
public static void inject(Context context, Object object) {
getInstance(context).inject(object);
}
public static void inject(Context context) {
inject(context, context);
}
public static void injectIfNull(Context context, Object object) {
if (object == null) {
inject(context, context);
}
}
public static void inject(Fragment fragment) {
inject(fragment.getActivity(), fragment);
}
public static MainApplication getInstance(Context context) {
if (context instanceof MainApplication) {
return (MainApplication) context;
} else if (context instanceof Activity) {
return getInstance(((Activity) context).getApplication());
} else if (context instanceof Service) {
return getInstance(((Service) context).getApplication());
} else if (context != null) {
Context applicationContext = context.getApplicationContext();
if (applicationContext instanceof MainApplication) {
return (MainApplication) applicationContext;
} else if (instance == null) {
setInstance(new MainApplication(applicationContext));
}
return instance;
}
return instance;
}
@Override
public synchronized void inject(Object object, Class> module) {
if (graph == null) {
buildRecargaGraph();
}
graph.inject(object);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// if(!BuildConfig.RELEASE) {
androidx.multidex.MultiDex.install(this);
// }
}
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
@Override
public void onCreate() {
try {
Class.forName("android.os.AsyncTask");
sDefSystemLanguage = Locale.getDefault().getLanguage();
} catch (Throwable ignore) {
// Desperate attempt to avoid java.lang.NoClassDefFoundError:
// android.os.AsyncTask
// For more info see: http://stackoverflow.com/a/27361430/901465
}
super.onCreate();
setInstance(this);
// workaround https://code.google.com/p/android/issues/detail?id=56296
getResources();
FacebookHelper.activateApp(this);
initReact();
HelpshiftWrapper.init(this);
initLeanplum();
registerContactsContentObserver();
initWebview();
}
private void initWebview() {
try {
try {
android.webkit.CookieSyncManager.createInstance(this);
// unrelated, just make sure cookies are generally allowed
android.webkit.CookieManager.getInstance().setAcceptCookie(true);
} catch (Exception ignore) {
}
// magic starts here
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null,
java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);
if (!BuildConfig.RELEASE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
} catch (Exception ignore) {
}
}
public void clearWebview() {
try {
if (android.webkit.CookieManager.getInstance() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
android.webkit.CookieManager.getInstance().removeAllCookies(new ValueCallback() {
@Override
public void onReceiveValue(Boolean value) {
Log.d("MainApplication", "Webview cookies removed" + value);
}
});
} else {
android.webkit.CookieManager.getInstance().removeAllCookie();
}
}
} catch (Exception ignore) {
Log.e("MainApplication", "Webview cookies failed", ignore);
}
}
private void initLeanplum() {
Leanplum.setApplicationContext(this);
Parser.parseVariables(this);
// For session lifecyle tracking.
LeanplumActivityHelper.enableLifecycleCallbacks(this);
// Insert your API keys here.
// Switch to your app using the app switcher at the top of the dashboard to view
// your keys.
if (BuildConfig.RELEASE) {
Leanplum.setAppIdForProductionMode("aa",
"a");
} else {
Leanplum.setAppIdForDevelopmentMode("aa",
"a");
}
Leanplum.enableVerboseLoggingInDevelopmentMode();
LeanplumPushService.setCustomizer(new LeanplumPushNotificationCustomizer() {
@Override
public void customize(Notification.Builder builder, Bundle bundle, @Nullable Notification.Style style) {
}
@Override
public void customize(NotificationCompat.Builder builder, Bundle notificationPayload) {
recarga.notificationService.buildNotification(builder, notificationPayload);
}
});
LeanplumActivityHelper.deferMessagesForActivities(WalkthroughActivity.class);
}
private void registerContactsContentObserver() {
try {
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true,
new ContactsObserver(null));
} catch (Throwable e) {
// Log.e("ContentObserver", e.getMessage(), e);
}
}
// workaround https://code.google.com/p/android/issues/detail?id=56296
@Override
public Resources getResources() {
if (mResources == null) {
final Resources resources = (Leanplum.isResourceSyncingEnabled()
? new LeanplumResources(super.getResources())
: super.getResources());
if (resources != null) {
mResources = resources;
}
}
return mResources;
}
@Override
public void onLowMemory() {
super.onLowMemory();
mResources = null;
if (recarga != null) {
if (recarga.cachedRequestService != null) {
recarga.cachedRequestService.clearMemoryCache();
}
if (recarga.localObjectStore != null) {
recarga.localObjectStore.clearMemoryCache();
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
try {
if (sDefSystemLanguage != null && !sDefSystemLanguage.equals(newConfig.locale.getLanguage())) {
// Start Sync context.
DataSyncService.start(this);
for (String type : ShareService.RAF_CONTEXT_TYPES) {
recarga.userService.getRafContext(true, type);
}
sDefSystemLanguage = newConfig.locale.getLanguage();
}
} catch (Throwable e) {
Log.e("Recarga", e.getMessage(), e);
}
}
private synchronized void buildRecargaGraph() {
if (graph == null) {
recarga = new RecargaHolder();
if (getBaseContext() != null && getApplicationContext() != null) {
recarga.applicationModule = new ApplicationModule(this);
} else {
recarga.applicationModule = new ApplicationModule(this.tmpContext);
}
ObjectGraph g = ObjectGraph.create(recarga.applicationModule);
g.inject(recarga);
recarga.errorService.setRouterService(recarga.routerService);
recarga.errorService.setUserService(recarga.userService);
recarga.preferencesService.setContextService(recarga.contextService);
recarga.preferencesService.setNotificationService(recarga.notificationService);
recarga.notificationService.setUserService(recarga.userService);
recarga.notificationService.setContextService(recarga.contextService);
recarga.trackingService.setPreferencesService(recarga.preferencesService);
recarga.trackingService.setUserService(recarga.userService);
recarga.trackingService.enableAdvertising();
recarga.trackingService.setFacebookHelper(recarga.facebookHelper);
recarga.trackingService.setEventsService(recarga.eventsService);
recarga.trackingService.initAppsFlyer(this);
recarga.helpshiftWrapper.setPreferencesService(recarga.preferencesService);
recarga.helpshiftWrapper.setRouterService(recarga.routerService);
recarga.userService.setErrorService(recarga.errorService);
recarga.userService.setRouterService(recarga.routerService);
recarga.authenticationService.setUserService(recarga.userService);
recarga.authenticationService.setRequestHeadersInjector(recarga.requestHeadersInjector);
recarga.authenticationService.setRouterService(recarga.routerService);
recarga.safetyNetCollector.setUsersService(recarga.userService);
recarga.routerService.setNotificationService(recarga.notificationService);
recarga.contactsService.setNotificationService(recarga.notificationService);
graph = g;
updateMessagingRegistrationAndInstallEventIfNecessary();
syncContactsIfNecessary();
}
}
public void updateMessagingRegistrationAndInstallEventIfNecessary() {
new AsyncTask() {
@Override
protected Void doInBackground(Void... params) {
try {
synchronized (lockRegistration) {
if (recarga != null && recarga.preferencesService != null
&& instance.getBaseContext() != null) {
boolean shouldSendInstallEvent = recarga.preferencesService.shouldSendNewInstallEvent();
if (recarga.notificationService.shouldUpdateMessagingRegistration()
|| shouldSendInstallEvent) {
RegistrationIntentService.event(MainApplication.this,
shouldSendInstallEvent ? RegistrationIntentService.POST_STATS_EVENT_INSTALL
: null);
}
}
}
} catch (Throwable e) {
Log.e("Recarga", e.getMessage(), e);
}
return null;
}
}.execute();
}
private void syncContactsIfNecessary() {
if (recarga.preferencesService.isContactsServiceHashDirty()) {
recarga.contactsService.storeContactsInServerInBackground(true);
}
}
static class RecargaHolder {
ApplicationModule applicationModule;
@Inject
AuthenticationService authenticationService;
@Inject
PreferencesService preferencesService;
@Inject
NotificationService notificationService;
@Inject
RouterService routerService;
@Inject
ErrorService errorService;
@Inject
UserService userService;
@Inject
ContextService contextService;
@Inject
TrackingService trackingService;
@Inject
HelpshiftWrapper helpshiftWrapper;
@Inject
CachedRequestService cachedRequestService;
@Inject
DiskBasedCache diskBasedCache;
@Inject
PromiseRequestQueue promiseRequestQueue;
@Inject
RequestHeadersInjector requestHeadersInjector;
@Inject
AndroidDeferredManager deferredManager;
@Inject
RequestQueue requestQueue;
@Inject
UiLifecycleHelper uiLifecycleHelper;
@Inject
FacebookHelper facebookHelper;
@Inject
SafetyNetCollector safetyNetCollector;
@Inject
RecargaEventsService eventsService;
@Inject
@Named("localObjectStore")
CachedObjectStore localObjectStore;
@Inject
ContactsService contactsService;
}
public PreferencesService getPreferencesService() {
if (recarga == null || recarga.preferencesService == null) {
buildRecargaGraph();
}
return recarga.preferencesService;
}
public TrackingService getTrackingService() {
if (recarga == null || recarga.trackingService == null) {
buildRecargaGraph();
}
return recarga.trackingService;
}
public UserService getUserService() {
if (recarga.userService == null) {
buildRecargaGraph();
}
return recarga.userService;
}
public FacebookHelper getFacebookHelper() {
if (recarga == null || recarga.facebookHelper == null) {
buildRecargaGraph();
}
return recarga.facebookHelper;
}
private class ContactsObserver extends ContentObserver {
/**
* Creates a content observer.
*
* @param handler The handler to run {@link #onChange} on, or null if none.
*/
private ContactsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
if (recarga != null && null != recarga.contactsService && null != recarga.preferencesService) {
if (recarga.preferencesService.hasSeenP2PContacts()) {
recarga.contactsService.storeContactsInServerInBackgroundDelayed();
}
}
}
}
private static String CODE_PUSH_PRODUCTION_KEY = "1";
private static String CODE_PUSH_STAGING_KEY = "2";
private static String CODE_PUSH_QA_KEY = "3";
public class MainReactNativeHost extends ReactNativeHost implements ReactInstanceHolder {
protected MainReactNativeHost(Application application) {
super(application);
}
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected List getPackages() {
String codePushDeploymentKey;
try {
String codePushEnvironment = getPreferencesService().getCodePushEnvironment();
if (codePushEnvironment.equals("qa")) {
codePushDeploymentKey = CODE_PUSH_QA_KEY;
} else if (codePushEnvironment.equals("st")) {
codePushDeploymentKey = CODE_PUSH_STAGING_KEY;
} else {
codePushDeploymentKey = CODE_PUSH_PRODUCTION_KEY;
}
} catch (Throwable e) {
Log.e("React", e.getMessage(), e);
codePushDeploymentKey = CODE_PUSH_PRODUCTION_KEY;
}
List packages = new PackageList(this).getPackages();
packages.add(new CodePush(codePushDeploymentKey, getApplicationContext(), !BuildConfig.RELEASE));
packages.add(new RecargaPackage());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Class.forName("android.bluetooth.le.ScanRecord");
packages.add(
(ReactPackage) Class.forName("it.innove.BleManagerPackage").getConstructor().newInstance());
packages.add((ReactPackage) Class.forName("me.pagar.mposnative.RNMposNativePackage").getConstructor()
.newInstance());
} catch (Exception e) {
Log.e("React", e.getMessage(), e);
}
}
return packages;
}
}
private final MainReactNativeHost mReactNativeHost = new MainReactNativeHost(this);
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
private void initReact() {
try {
SoLoader.init(this, /* native exopackage */ false);
CodePush.setReactInstanceHolder(mReactNativeHost);
initializeFlipper(this); // Remove this line if you don't want Flipper enabled
} catch (Exception e) {
Log.e("React", e.getMessage(), e);
}
}
/**
* Loads Flipper in React Native templates.
*
* @param context
*/
private static void initializeFlipper(Context context) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
```
#### `AndroidManifest.xml`:
```xml
```
Environment
Click To Expand
**`react-native info` output:** ``` System: OS: macOS Mojave 10.14.5 CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz Memory: 134.43 MB / 8.00 GB Shell: 5.3 - /bin/zsh Binaries: Node: 12.12.0 - ~/.nvm/versions/node/v12.12.0/bin/node Yarn: 1.19.2 - /usr/local/bin/yarn npm: 6.11.3 - ~/.nvm/versions/node/v12.12.0/bin/npm SDKs: iOS SDK: Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1 Android SDK: API Levels: 23, 24, 25, 26, 27, 28, 29 Build Tools: 27.0.3, 28.0.2, 28.0.3 System Images: android-27 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom_64 Android NDK: 20.0.5594570 IDEs: Android Studio: 3.5 AI-191.8026.42.35.5900203 Xcode: 11.3/11C29 - /usr/bin/xcodebuild npmPackages: react: 16.9.0 => 16.9.0 react-native: 0.61.2 => 0.61.2 ``` - **Platform that you're experiencing the issue on**: - [ ] iOS - [x] Android - [ ] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - 6.0.1 - **Are you using `TypeScript`?** - No