React-native-firebase: AndroidX support

Created on 12 Oct 2018  路  46Comments  路  Source: invertase/react-native-firebase

[Edited: Note for people that want to use AndroidX - it is possible]

:arrow_down_small: please see the comment below :arrow_down_small:

https://github.com/invertase/react-native-firebase/issues/1588#issuecomment-503094221

Most helpful comment

Play Services just shipped AndroidX breaking changes - if you must upgrade your android Firebase SDK dependencies

  • convert your project to AndroidX via AndroidStudio following their instructions
  • npm i jetifier
  • hook a call to npx jetify in postinstall (and run it once yourself) to process node_modules source.

Then it will likely work (it worked for me).


Update 20190811 - To be clear on one thing - there is a change on the tip of the v5.x.x branch that is unreleased (it will be in 5.5.7) that allows for better library specification for AndroidX in react-native 0.60 - I use the branch reference as my dependency currently: https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh#L12

https://github.com/invertase/react-native-firebase/pull/2476

But everything continues to work for me, I have successfully completed a migration to react-native 0.60.4 + AndroidX + Cocoapods and it hurt to do, but it all works with issues in react-native-firebase fixed along the way. Cheers

All 46 comments

@OleksandrKucherenko it is something that I'd like to switch over to eventually yes, I've quickly gone through the project and checked what we use it for overall, the majority of it was NonNull/Nullable annotations - I've just switched all these over to use javax.annotation.Nonnull/Nullable; (here) and after that all that remains is the following:

image

The 2x RequiresPermission ones will be obselete in v6 as these will move into the packages AndroidManifest files.

All that remains then is the usage in Notifications & Messaging, if you'd like to send a PR for this that'd be super handy - it might not get a direct merge but it would definitely form the basis of swapping it out for v6.0.0.

If you could come on our discord chat I'd be up for chatting about it and if there's anything else Android side that you think needs doing 馃憤


Loving react-native-firebase and the support we provide? Please consider supporting us with any of the below:

Hi. Would just like to note that I have just tried to upgrade to AndroidX as an attempt to solve some support library dependency issues in other packages. Unfortunately the only thing blocking me now is react-native-firebase - (android.support.annotation does not exist). Are there any plans to make the changes at this stage? Thanks!

@sinewave440hz you can use old android.support.annotations library. Its just an annotation classes that are not used in runtime, they only used for Android Studio IDE (Intellij) for validating parameters of methods, call sequence, multi-threading requirements, etc. Including of OLD (not androidx support library with annotations will not make any harm).

I see. Given that I've otherwise successfully built my app using AndroidX, could you suggest more specifically how I can get my app to build? I have 20 errors that are related to this that I'm not sure how to fix:

error: package android.support.annotation does not exist
error: package android.support.v4.content does not exist
error: cannot find symbol variable LocalBroadcastManager
error: cannot find symbol class RemoteInput
error: package android.support.v4.content does not exist
error: cannot find symbol class LocalBroadcastManager
error: cannot find symbol variable RemoteInput
error: cannot find symbol class NotificationCompat
error: package NotificationCompat does not exist
error: package NotificationCompat.Action does not exist
error: cannot find symbol class RemoteInput
error: package RemoteInput does not exist
error: package android.support.annotation does not exist
error: cannot find symbol class RequiresPermission
error: cannot find symbol variable LocalBroadcastManager

Did the lib been upgraded to androidx?

Is there a workaround for this? New versions of other libraries require us to upgrade to AndroidX and then we're stuck not able to build, because of this issue. :( Version 6 feels like it could take months.

I thought this is going to be solved by jetifier... but I have it enabled and still firebase is giving me these errors.


Edit: For anyone else, the workaround is this:
Add gradle.properties into the android folder of each incompatible module, with this content:

android.useAndroidX=false
android.enableJetifier=false
  • version 6 will take months, that's public information
  • the AndroidX conversion performed by jetifier is not possible for dependencies included by source, and by default react-native includes things via source inclusion - jetifier only transforms jars/aars
  • the community in general is discussing how to handle this since react-native 0.60 will be AndroidX and that starts to move all the libraries. You will likely want to follow the issue: https://github.com/react-native-community/discussions-and-proposals/issues/129

My best guess now is that react-native libraries will need to be delivered as AARS so jetifier can work forwards (for those libraries that have not converted, like react-native-firebase v5) and with an support-library compatibility AAR distributed for those apps that can't convert.

You could try packaging the react-native-firebase v5 code into a JAR and adding it as a local dependency yourself if you like, jetifier would work then.

Interesting workaround by the way - you could use patch-package (works really really well) to automate that patch if/until libraries adopt it, if it works well

Interesting workaround by the way - you could use patch-package (works really really well) to automate that patch if/until libraries adopt it, if it works well

Yerp, for example this is how people can use v6 now without AndroidX if they need to, here's the patch I've been recommending:

diff --git a/node_modules/@react-native-firebase/app/android/gradle.properties b/node_modules/@react-native-firebase/app/android/gradle.properties
index d015431..e69de29 100644
--- a/node_modules/@react-native-firebase/app/android/gradle.properties
+++ b/node_modules/@react-native-firebase/app/android/gradle.properties
@@ -1,2 +0,0 @@
-android.useAndroidX=true
-android.enableJetifier=true
\ No newline at end of file
diff --git a/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java b/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java
index 521a2e0..d63afae 100644
--- a/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java
+++ b/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java
@@ -17,7 +17,7 @@ package io.invertase.firebase.app;
  *
  */

-import androidx.annotation.Keep;
+import android.support.annotation.Keep;

 import com.google.firebase.components.Component;
 import com.google.firebase.components.ComponentRegistrar;
diff --git a/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java b/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java
index 5b1726b..5970656 100644
--- a/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java
+++ b/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java
@@ -19,7 +19,7 @@ package io.invertase.firebase.common;

 import android.os.Handler;
 import android.os.Looper;
-import androidx.annotation.MainThread;
+import android.support.annotation.MainThread;
 import android.util.Log;

 import com.facebook.react.bridge.Arguments;
diff --git a/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java b/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java
index 42fec16..fcf0c42 100644
--- a/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java
+++ b/node_modules/@react-native-firebase/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java
@@ -23,7 +23,7 @@ import android.content.Context;
 import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.net.Uri;
-import androidx.annotation.Nullable;
+import android.support.annotation.Nullable;

 import javax.annotation.OverridingMethodsMustInvokeSuper;

Took me ~5 mins to generate that, if people really need something then there are ways 馃檭 for both ways AndroidX removal or AndroidX converting.


Version 6 feels like it could take months.

If more people contributed this would go a lot quicker. I myself am majorly burnt out working on v6 but I'm still going, hearing stuff like this isn't motivating me I can tell you that. 馃槱 There are only 2 maintainers working on this + @mikehardy actively helping out with issues, testing & triage.

If anyone wants it quicker then I'd suggest contributing time or donating to pay for other contributors time. Not to rant though, I just genuinely wish more people contributed, /dreams

Interestingly, it looks like all your support usage is annotations? Nullable is just a lint hint and the Keep might be implemented in a packaged proguard rule - you might be upgradable to androidx by deleting all references ;-). And yes, always better when the level of contribution rises to the level of requests for help :)

@mikehardy indeed it's all annotations currently - until we hit messaging & AdMob, at which point the usages goes way beyond that 馃槥 but doesn't stop them being removed from the other modules I guess 馃

Oh - if it goes beyond that I'd just ignore it then, it's a binary thing you either need androidx or not and if you can't get to zero save the time.

I believe we're going to have a solution soon, there were some good AndroidX + react-native library results last night. We might be down to just making nitty-gritty tooling / CLI decisions shortly

Play Services just shipped AndroidX breaking changes - if you must upgrade your android Firebase SDK dependencies

  • convert your project to AndroidX via AndroidStudio following their instructions
  • npm i jetifier
  • hook a call to npx jetify in postinstall (and run it once yourself) to process node_modules source.

Then it will likely work (it worked for me).


Update 20190811 - To be clear on one thing - there is a change on the tip of the v5.x.x branch that is unreleased (it will be in 5.5.7) that allows for better library specification for AndroidX in react-native 0.60 - I use the branch reference as my dependency currently: https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh#L12

https://github.com/invertase/react-native-firebase/pull/2476

But everything continues to work for me, I have successfully completed a migration to react-native 0.60.4 + AndroidX + Cocoapods and it hurt to do, but it all works with issues in react-native-firebase fixed along the way. Cheers

Since version 6 may take months as authors say, I suppose because it takes care of so many other things besides Android X, I have forked into my space and will try to make a package with only Android X support applied to version [email protected]. I have published the working version at:

https://www.npmjs.com/package/react-native-firebase-with-android-x

I hope it will work soon and it helps someone (and me).

@dmaksimovic this shouldn't be necessary - I have successfully used the v5.5 with the AndroidX play services + firebase SDKs that just shipped, along with npm i jetifier && npx jetify and it works fine.

Also, there is already a 5.5.1 and will be a 5.5.2 as soon as all this AndroidX nonsense dies down enough to make sure I got all the breaking changes introduced by iOS 6.x pods - you'll be incurring maintenance burden for no reason when jetify works

Better to try a PR for the bob + reverse-jetified aar mentioned here https://github.com/react-native-community/discussions-and-proposals/issues/129 - then we can move to androidx for real

I didn't mean to maintain this, and it should work only for Android, it's just meant to be as the first aid. I'll also try your proposed solution with jetify. Thanks

Till react-native-firebase officially supports AndroidX i have used below steps to generate apk.

After migrating to Android X.
I was getting errors w.r.t react-native-firebase

> Task :react-native-firebase:compileDebugJavaWithJavac FAILED /node_modules/react-native-firebase/android/src/main/java/io/invertase/firebase/ReactNativeFirebaseAppRegistrar.java:20: error: package android.support.annotation does not exist import android.support.annotation.Keep; ^ /node_modules/react-native-firebase/android/src/main/java/io/invertase/firebase/ReactNativeFirebaseAppRegistrar.java:29: error: cannot find symbol @Keep

This Link contains mapping for all packages.
Just search the package mentioned in error on the link and replace with respective mapping.

for example in above stack-trace:
android.support.annotation.Keep needs to be replaced with androidx.annotation.Keep

Hope it helps.

@zashishz that is a manual and error-prone process that will be undone every time you install the package in a new location or or install an update. There is no need to do that, or for the library to upgrade yet (which would strand people that can't update). Use npm i jetifier && npx jetify as a postinstall step in package.json and it should work for you.

@mikehardy yes i agree my workaround will not work on new location/installs.
I needed to generate an android build urgently. Hence, thought of using it this way till its officially supported.

Will try your solution too. Thanks

@mikehardy Ok, I'm deleting the repo and module I created, as it's redundant and may produce confusion. Thanks and keep up the good work!

@dmaksimovic okay - thinking forward - if you are interested and want to make a lasting impact you could try making a fork of jetify and implementing the "reverse-jetify" mode, then we could move this library recommend reverse-jetify for the opposite case - people that are stuck on support libraries but still want our bugfixes. Then you could PR what you had in your fork and we all move forward bit by bit :-)

After hitting refractor->migrate to androidX for the top menu in android studio I had some issues.

I changed all (4 files)
import android.support.v4.content.LocalBroadcastManager;
to
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

Then now it compiles.

@venux92 unnecessary to do manual changes, those will be reverted next time you update anyway - use the automated tools developed by the community: https://github.com/mikehardy/jetifier and hook them in postinstall

(this was covered above)

@mikehardy I have tried your approach but when I run yarn run jetify or npx jetify I get:
yarn: The system cannot find the path specified. error Command failed with exit code 1.
npx: The system cannot find the path specified.

@edenkras head over to the jetifier repo, examine the instructions and troubleshooting etc and log an issue there if it it persists

Play Services just shipped AndroidX breaking changes - if you must upgrade your android Firebase SDK dependencies

  • convert your project to AndroidX via AndroidStudio following their instructions
  • npm i jetifier
  • hook a call to npx jetify in postinstall (and run it once yourself) to process node_modules source.

Then it will likely work (it worked for me).

May I say, THANK YOU?
After merging to AndroidX last week, I was still having compile errors from two dependencies: ':react-native-image-picker' & ':react-native-firebase'
Based on your tip, I ran
npm i jetifier
then I ran
npx jetify
That was all I did, and now the following commands will build successfully without error, when they were not previously.
react-native run-android
./gradlew lint
./gradlew assembleRelease

I seem to finally be back on track to finishing my app now after the breaking changes I discovered last Tuesday.

So again, I thank you.

You鈥檙e welcome! Glad it helped. Remember to hook the jetifier call in package.json postinstall or you鈥檒l blow up unexpectedly again after any module upgrades :-)

@EskelCz you saved my live 馃憤 I'm new to the "switching to androidX" mess and spend a few evenings trying to fix the build (in an app that has to be on Google Play on Monday...), thanks!

@michaelkowalski replying to say that @EskelCz solution is out of date and I would not recommend it. Altering things in node_modules is a last resort, and even if you did it you would want to use patch_package. The current community recommendation for an AndroidX migration is to use Android Studio to migrate your current app, and then to use the jetifier npm package with a hook to jetify in your postinstall to maintain the migration in dependent packages source if new versions come down or you install new packages

@mikehardy thanks for your reply! Yes, I saw the rest of the discussion and agree that it's far from the best solution. However for a quick fix it's great because it lets me generate the apk. After the Monday release I will certainly come back here and fix the issue in a more elegant way :)

EDIT: ok, I did it now ;) works like a charm. Thanks for the library! However I had to install jetifier by yarn, the npm way led me to not being able to execute the command.

The issue still persists for me, I am using androidX and enableJetifier

android.useAndroidX=true
android.enableJetifier=true

Packages:

    "react-native-fbsdk": "^0.10.1",
    "react-native-firebase": "^5.5.4",

I am now only getting three errors:
Screenshot 2019-07-01 at 14 03 26

I've added jetifier and run npx jetify once, I've also added as a postinstall hook for future. If I got to migrate to AndroidX it confirms there are no more file changes required.

Any other thoughts on this @mikehardy, Thank you

I am unable to reproduce - works for me with jetifier
clone that and go JETIFY=true ./make-demo.sh in the directory, compiles fine?
https://github.com/mikehardy/rnfbdemo/commit/580d50857e2d0d4784704d9a007152cc75a37e3c

I'm having the same problem with @StuartMorris0

I worked with update core android from normal to androidX lib
You can see: https://developer.android.com/jetpack/androidx/migrate

I would say upgrade core to implementation 'com.google.firebase:firebase-core:17.0.0' beside using jetifier works for me

Manually changing all the deprecated Imports to the new Androidx ones worked for me:
Migrating to AndroidX

You guys, the jetifier javascript package does that for you. Or, you can manually change the imports on every new install of every new version on every new machine - your choice I suppose?

The two commands that @mikehardy suggested worked for me.
In my package.json I added those commands:

 "scripts": {
        "postinstall": "npm i jetifier && npx jetify"
    }

To make this work just delete node_module folder(rm -rf node_modules) and npm install.

If this does not work for you, you can add your own script and added it in "postinstall", Eg:

 "scripts": {
        "postinstall": "node ./scripts/packageFixer.js"
    }

and your packageFixer.js file is going to look like this:

const fs = require('fs');
filePath = './node_modules/react-native-firebase/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessaging.java',
codeToFind = /android\.support\.v4\.content\.LocalBroadcastManager/;
replacement = 'androidx.localbroadcastmanager.content.LocalBroadcastManager';
fileContent = fs.readFileSync(filePath,'utf8');
fs.writeFileSync(filePath, fileContent.replace(codeToFind, replacement), { encoding: 'utf8' });

This approach requires more work but can help you. You will need to repeat this script(not file) for each file that needs androidx

I'm still stuck on these dependency issues. Not sure what the cause of it is, but it only started once I upgraded to RN 60.

ERROR: Unable to resolve dependency for ':react-native-firebase@debug/compileClasspath': Could not resolve com.google.code.findbugs:jsr305:{strictly 3.0.0}.
Show Details
Affected Modules: android-react-native-firebase


ERROR: Unable to resolve dependency for ':react-native-firebase@debug/compileClasspath': Could not resolve com.squareup.okhttp:okhttp:{strictly 2.5.0}.
Show Details
Affected Modules: android-react-native-firebase
subprojects {
    configurations.all {
        // exclude OLD versions of OKHTTP library
        exclude group: 'com.squareup.okhttp', module: 'okhttp'

        // exclude rxJava v1.xxx
        exclude group: 'io.reactivex', module: 'rxjava'
        exclude group: 'io.reactivex', module: 'rxandroid'

        resolutionStrategy {
            failOnVersionConflict()
            preferProjectModules()

            eachDependency { details ->

                /* Override by group and library names */
                def name = "${details.requested.group}:${details.requested.name}"
                switch (name) {
                    // https://github.com/square/okhttp/blob/master/CHANGELOG.md
                    case 'com.squareup.okhttp3:okhttp':
                        /* Latest low level HTTP communication lib */
                        details.useVersion '3.12.1'
                        break

                    /* API compatible, https://medium.com/square-corner-blog/okio-2-6f6c35149525 */
                    case 'com.squareup.okio:okio': details.useVersion '2.1.0'; break

                    case 'com.google.code.findbugs:jsr305': details.useVersion '3.0.2'; break
                    case 'androidx.appcompat:appcompat': details.useVersion '1.0.2'; break
                    case 'androidx.core:core': details.useVersion '1.0.1'; break
                    case 'androidx.vectordrawable:vectordrawable': details.useVersion '1.0.1'; break
                }
            }
        }
    }
}

@ccorcos ^ - try such overrides for gradle dependencies

@OleksandrKucherenko that is some serious groovy code for gradle! It looks right (except maybe you could bump gradle to 3.12.3 (vs 3.12.1) - it is the latest that is still compatible down to API16 (for react-native)

May I ask you to share your react-native native module dependency list so I could get an idea of which libraries are causing such conflicts? Because with my dependency list I don't have conflicts. I suspect maybe code-push or expokit but I'd like to see. Thanks!

@mikehardy In my case overrides used for the project that has a dependency to ~20 react-native packages. Unfortunately, not all modules are updated to the latest versions, or even have a version that is compatible with AndroidX.

that why born this code with global overrides, that deeply force versions of a specific java/android libs in all configurations.

Most issues with RN 0.6x and AndroidX were in alignment/sync of different configurations used in the project. After such override all errors from build plugins, versions mismatch are gone. BUT it quite risky, no one guaranty backward compatibility (exception is only okhttp lib).

So test your project carefully, upgrade version of each dependency and "commit" the result if app running well.

I just spent couple days migrating our whole app from RN 0.53 to 0.60.5.

The example provided by @mikehardy was a life saver.

At one point I was doing:

yarn add 3rd-party-library
rm -rf node_modules
rm yarn.lock
yarn
npx jetify
npx react-native run-android

with every dependency in the project. Probably over the top, but after 2 days of getting random gms dependency issues, I didn't care. That worked.

Thanks @mikehardy, you are the man!

Glad that helped, the rn60 upgrade is rough but your project is probably sparkly clean now ;-) - I know mine was pretty spiffy when I was done with it

Is there a workaround for this? New versions of other libraries require us to upgrade to AndroidX and then we're stuck not able to build, because of this issue. :( Version 6 feels like it could take months.

I thought this is going to be solved by jetifier... but I have it enabled and still firebase is giving me these errors.

Edit: For anyone else, the workaround is this:
Add gradle.properties into the android folder of each incompatible module, with this content:

android.useAndroidX=false
android.enableJetifier=false

It may cause to other dependencies

As this is one of google top result:
Updating React-Native-Firebase to 5.6.0 did solve the issue for me. (Jetify did not solve the problem)

Was this page helpful?
0 / 5 - 0 ratings