exponea / exponea-react-native-sdk

MIT License
8 stars 13 forks source link

Intialisation issues with @react-native-firebase dependencies on Android #3

Closed Eluinhost closed 4 years ago

Eluinhost commented 4 years ago

We noticed that including exponea-react-native-sdk caused initialisation issues when we already had react-native firebase dependencies setup.

error screen

We eventually came to a fix/workaround of forcing an initialise for DEFAULT in the MainApplication#onCreate:

io.invertase.firebase.app.ReactNativeFirebaseApp.initializeSecondaryApp("[DEFAULT]", this);

This is only an issue on Android, we've not came across any issues on iOS.

Replication repo can be found here: https://github.com/Eluinhost/ExponeaWithFirebaseExample This is a fresh init react-native app with firebase and exponea setup, instructions are in the README.md

wassil commented 4 years ago

I'll add this to our backlog, either will find a way to fix this(if possible) or add the information into documentation.

Thank you for the awesome report! And for being brave and testing this out 🥇

rkaartikeyan commented 4 years ago

@Eluinhost Thanks for the workaround, the App is launching successfully now, but still I am getting the below error.

2020-11-10 16:15:05.253 27869-27869/com.crashlyticspoc E/RNFBCrashlyticsInit: initialization failed
    java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.crashlyticspoc. Make sure to call FirebaseApp.initializeApp(Context) first.
        at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:184)
        at com.google.firebase.crashlytics.FirebaseCrashlytics.getInstance(FirebaseCrashlytics.java:229)
        at io.invertase.firebase.crashlytics.ReactNativeFirebaseCrashlyticsInitProvider.onCreate(ReactNativeFirebaseCrashlyticsInitProvider.java:54)
        at android.content.ContentProvider.attachInfo(ContentProvider.java:2388)
        at android.content.ContentProvider.attachInfo(ContentProvider.java:2358)
        at io.invertase.firebase.common.ReactNativeFirebaseInitProvider.attachInfo(ReactNativeFirebaseInitProvider.java:35)
        at android.app.ActivityThread.installProvider(ActivityThread.java:7239)
        at android.app.ActivityThread.installContentProviders(ActivityThread.java:6780)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6697)
        at android.app.ActivityThread.access$1300(ActivityThread.java:237)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Can you please let me know do you also getting the same error?

wassil commented 4 years ago

Hi, what versions of firebase packages are you using?

rkaartikeyan commented 4 years ago

@wassil below is my package.json

{
  "name": "CrashLyticsPoc",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@react-native-firebase/analytics": "^7.6.9",
    "@react-native-firebase/app": "^8.4.7",
    "@react-native-firebase/crashlytics": "^8.4.12",
    "@react-native-firebase/perf": "^7.4.10",
    "@react-native-firebase/remote-config": "^9.0.12",
    "react": "16.9.0",
    "react-native": "0.61.5",
    "react-native-exponea-sdk": "^0.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/runtime": "^7.6.2",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-jest": "^24.9.0",
    "eslint": "^6.5.1",
    "jest": "^24.9.0",
    "metro-react-native-babel-preset": "^0.56.0",
    "react-test-renderer": "16.9.0"
  },
  "jest": {
    "preset": "react-native"
  }
}
wassil commented 4 years ago

I've just tested the combination of packages and wasn't able to reproduce your issue. Maybe some part of your firebase setup is incorrect. I'd try removing the Exponea package and if the error persists, it mean there is an issue with your firebase setup. If you google the issue you're facing, you'll find a lot of different reasons why this may be happening.

rkaartikeyan commented 4 years ago

@wassil without rn exponea lib I couldn't see the error RNFBCrashlyticsInit: initialization failed, I am seeing the error after adding the rn exponea lib.

If you want I can record a video and share it with you via YouTube. For the past three days, I am trying to find a solution it's for one of Exponea's Client only.

wassil commented 4 years ago

My issue here is that I cannot reproduce it. When does the error occur? Do you have an example project you could share with me?

rkaartikeyan commented 4 years ago

@wassil https://github.com/rkaartikeyan/crashlytics-poc

Run the app after npm install, you will see the log(below) in the android studio's logcat.

2020-11-13 13:24:32.621 26975-26975/com.crashlyticspoc I/FirebaseCrashlytics: Initializing Crashlytics 17.2.2
2020-11-13 13:24:32.851 26975-26975/com.crashlyticspoc I/RNFBCrashlyticsInit: initialization successful
2020-11-13 13:24:32.871 26975-27013/com.crashlyticspoc I/FirebaseCrashlytics: Crashlytics NDK initialization successful
2020-11-13 13:24:36.906 26975-27050/com.crashlyticspoc I/ReactNativeJS: Running "CrashLyticsPoc" with {"rootTag":1}

then add exponea-react-native-sdk and run the app again you will see the crash which reported in this issue ticket.

so add io.invertase.firebase.app.ReactNativeFirebaseApp.initializeSecondaryApp("[DEFAULT]", this); in MainApplication#onCreate.

now the app will run successfully, but you will see the error E/RNFBCrashlyticsInit: initialization failed in logcat.

wassil commented 4 years ago

Hi, I was finally able to reproduce it. Looking into it right now.

ikarimmagdy commented 4 years ago

@wassil I am Karim From Alshaya and Photon team. Waiting your feedback asap. please as its a blocker for Today's release.

wassil commented 4 years ago

Got it: @react-native-firebase requires that Firebase is initialized using the default content provider https://github.com/firebase/firebase-android-sdk/blob/master/firebase-common/src/main/AndroidManifest.xml#L23

Our native Android SDK disables that content provider and rather initializes Firebase when the Exponea SDK is initialized. https://github.com/exponea/exponea-android-sdk/blob/develop/sdk/src/main/AndroidManifest.xml#L21

This is no longer required(since about a month ago) and will be changed in future release.

Most issues were fixed by the above statement that initialized Firebase in Application onCreate

@react-native-firebase/crashlytics however has a content provider with init order 98, and assumes that firebase was initialized, but it's not.

Instead of initializing Firebase in Application onCreate, we have to do it in a content provider with initOrder 100

<provider
        android:name="[YOUR-PACKAGE-NAME].InitProvider"
        android:authorities="${applicationId}.firebaseinitprovider"
        android:exported="false"
        android:initOrder="100" />

In the content provider, just initialize Firebase

package [YOUR-PACKAGE-NAME];

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.firebase.FirebaseApp;

public class InitProvider extends ContentProvider {
    private static final String TAG = "InitProvider";
    @Override
    public boolean onCreate() {
        if (FirebaseApp.initializeApp(getContext()) == null) {
            Log.i(TAG, "FirebaseApp initialization unsuccessful");
        } else {
            Log.i(TAG, "FirebaseApp initialization successful");
        }
        return false;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
        return null;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }
}

You'll need to add dependency on firebase-common in order for this to work

implementation 'com.google.firebase:firebase-common:19.3.1'

Consider this just a temporary solution, this will be fixed in future versions of the package

wassil commented 4 years ago

We've just released version 0.4.0, which uses a native Android SDK that doesn't disable default Firebase init.

With 0.4.0, the default Firebase instance is created and no hacks are required to set it up. Just include both Firebase and Exponea packages into your app and everything should work out of the box.