React-native-fcm: App crashes on receving notification

Created on 24 Feb 2018  路  7Comments  路  Source: evollu/react-native-fcm

I am using this package with expokit (detached). On sending the notifictaion the app crashes. I searched around to find that adding

compile 'com.google.firebase:firebase-messaging:11.8.0'

worked for some. But in my case it produces

Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex

Here's the app/build.gradle file

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    defaultConfig {
        applicationId "com.wow.wow"
        minSdkVersion 19
        targetSdkVersion 25
        multiDexEnabled true
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
        ndk {
            abiFilters 'armeabi-v7a', 'x86'
        }
        manifestPlaceholders = [
                'appAuthRedirectScheme': 'com.wow.wow'
        ]
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dexOptions {
        javaMaxHeapSize "8g"
    }
    lintOptions {
        abortOnError false
    }
}

task exponentPrebuildStep(type: Exec) {
    workingDir '../../'

    if (System.getProperty('os.name').toLowerCase().contains('windows')) {
        commandLine 'cmd', '/c', '.\\.expo-source\\android\\detach-scripts\\prepare-detached-build.bat'
    } else {
        commandLine './.expo-source/android/detach-scripts/prepare-detached-build.sh'
    }
}
preBuild.dependsOn exponentPrebuildStep

repositories {
    flatDir {
        dirs 'libs'
    }
    mavenLocal()
    maven { url 'https://maven.fabric.io/public' }
}

dependencies {
    compile (project(':react-native-fcm'))   {
        exclude group: 'com.google.android.gms'
        exclude group: "com.google.firebase"
    }

    compile 'com.google.firebase:firebase-core:11.8.0' //this decides your firebase SDK version
    compile 'com.google.firebase:firebase-messaging:11.8.0'
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:26.0.1'
    compile 'com.android.support:multidex:1.0.1'


    compile('host.exp.exponent:expoview:23.0.0@aar') {
        exclude group: 'com.facebook.android', module: 'facebook-android-sdk'
        exclude group: 'com.facebook.android', module: 'audience-network-sdk'
        exclude group: 'io.nlopez.smartlocation', module: 'library'
        transitive = true;
    }

    compile 'com.facebook.android:facebook-android-sdk:4.+'
    compile('com.facebook.android:audience-network-sdk:4.+') {
        exclude module: 'play-services-ads'
    }
    compile('io.nlopez.smartlocation:library:3.2.11') {
        transitive = false
    }


}
configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (details.requested.group == 'com.google.android.gms'
                && ( (details.requested.name == 'play-services-base') || (details.requested.name == 'play-services-maps') ) ) {
            details.useVersion '11.8.0'
        }
        if (details.requested.group == 'com.google.firebase') {
            details.useVersion '11.8.0'
        }
    }
}
apply plugin: 'com.google.gms.google-services'

Most helpful comment

@anish000kumar I used this trick. I'm not good at Java so I can't be sure this code is good. But my problem was solved.

public class MainApplication extends MultiDexApplication implements ReactApplication {
  public List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
      new FIRMessagingPackage()
    );
  }

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new FIRMessagingPackage()
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }
}

All 7 comments

@evollu Yes, I tried all the answers, but this one seems to be specific to expokit somehowe. The notifications are working when the app is not running, however if the app is open while sending notification from firebase, it crashes.
There's seems to be another open issue with same situation:
https://github.com/evollu/react-native-fcm/issues/756

FATAL EXCEPTION: main
     Process: com.wow.wow, PID: 6506
     java.lang.ClassCastException: com.wow.wow.MainApplication cannot be cast to com.facebook.react.ReactApplication
     at com.evollu.react.fcm.MessagingService$1.run(MessagingService.java:41)
     at android.os.Handler.handleCallback(Handler.java:790)
     at android.os.Handler.dispatchMessage(Handler.java:99)
     at android.os.Looper.loop(Looper.java:164)
     at android.app.ActivityThread.main(ActivityThread.java:6494)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Here's the error from logcat for better reference

com.wow.wow.MainApplication cannot be cast to com.facebook.react.ReactApplication
can't fix that piece. is there another way to integrate with expo?

There doesn't seem to be any specific approach to use a library with expo as such. After detaching to expoKit, other libraries are pretty much installed the same way as with normal CRN projects. Here's the link to the expokit detaching process (https://docs.expo.io/versions/latest/guides/detach.html), if that helps.

@anish000kumar I used this trick. I'm not good at Java so I can't be sure this code is good. But my problem was solved.

public class MainApplication extends MultiDexApplication implements ReactApplication {
  public List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
      new FIRMessagingPackage()
    );
  }

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new FIRMessagingPackage()
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }
}

implements ReactApplication should solve the issue

Was this page helpful?
0 / 5 - 0 ratings