The hardest thing i ever did
Updating react-native of version 0.68.2 to 0.72.4
Hey, how are you? I hope so. I recommend you grab a coffee because the title is not an odyssey by chance.
Recently while writing this text, I went through a very common situation in the life of any developer: updating a project that had been stopped for a few months and dealing with updating and versioning packages.
However, I didn't expect that this process would be heavier than I imagined (more complex than in the web environment).
And as a way to help me organize, I used the notepad to create a 'timeline' of attempts and useful links during the process.
Before I show you these notes, I want to give everyone context:
- Objective: Upload a new version of an app made in React Native to the Play Store
- Barrier: The Play Store did not accept API Level below 33 (or Android below 13)
- Solution: Update the app made in React Native from version 0.68.2 to 0.72.4
- Naming: I will treat the app name as 'updatedApp'
Note: each build or start test took around 15-20 minutes, meaning 3-4 builds per hour, 24 attempts per day (in an 8-hour workday).
With that in mind, let's go:
Updating with react-native-upgrade
After researching how to adapt my app to this new Android version, I came up with some solutions but couldn't avoid updating react-native itself. There might have been other ways to solve it, but the decision was made, so let's proceed.
I ran a react-native-upgrade, and knowing that I had to update a series of native files, I used the Upgrade helper as a guide. This tool was a lifesaver, thanks to the community 🙏
After implementing many corrections file by file, the first error that appeared was this:
Failed to apply plugin 'com.android.internal.version-check'.
- Minimum supported Gradle version is 7.5. Current version is 7.3.3.
- If using the gradle wrapper, try editing the distributionUrl in /updated-app/android/gradle/wrapper/gradle-wrapper.properties to gradle-7.5-all.zip
After fixing this guided by the Upgrade Helper and with the manual update of expo-modules, another problem arises:
another problem arises:
Uncaught Error Error: [ios.xcodeproj]: withIosXcodeprojBaseMod: Cannot find module './parse'
Require stack:
- ../.npm/_npx/d80a5a2fd0b43bdc/node_modules/install-expo-modules/build/index.js
After fixing this (which I don't remember how), another one appears:
Build file '.../updated-app/node_modules/expo-application/android/build.gradle' line: 40
As this one was more specific, the correction was easier, leading me to this warning: classifier undefined
During the research, I found this resource to solve the problem https://github.com/expo/fyi/blob/main/expo-modules-gradle8-migration.md
At this point, I had to ask for help from the Doctor
Since the last fix didn't work, I used npx expo-doctor (it lists exactly the libraries that need to be updated)
I ran the command where expo-doctor evaluates and installs the libraries accordingly (expo doctor --fix-dependencies)
New error:
A problem occurred configuring project ':app'. Cannot query the value of extension 'react' property 'entryFile' because it has no value available.
Along with this error, when running expo-doctor, it pointed out that I was using version x of @expo/config-plugins and wanted version y, even though I had version y
After asking ChatGPT how to solve this issue with @expo/config-plugins, I deleted node_modules and installed everything again with yarn (nothing happened feijoada)
After debugging with ./gradlew assembleRelease --scan, I saw that it was related to expo-updates-gradle-plugin.
Insight: I understood that the version of @expo/config-plugin I have in the project is correct, but other libraries that have it as a dependency are using earlier versions
I updated the version of each of those dependencies in the yarn.lock, and expo-doctor didn't point out anything anymore. However, the same error persists when running yarn android:
(Cannot query the value of extension 'react' property 'entryFile' because it has no value available)
I entered the android/app/build.gradle file and uncommented the line with 'entryFile,' and it almost worked (the build was 100% configured but crashed in execution)
Updating with expo update
I found out that I was going through this whole process with react-native upgrade, which tends to be more complicated indeed https://www.youtube.com/watch?v=Y9ihngV85w8, so let's try with expo update.
I cloned the project again to keep both attempts (expo update and react native upgrade) in different folders.
After running expo update, I ran npx expo install --fix, and I returned to the same problem with @expo/config-plugins.
Note: most likely, these guys were messing things up
- react-native-iap: "^12.10.7"
- @react-native-firebase/app: "^16.4.6"
After evaluating the code, I realized that the react-native-iap lib wasn't being used, so I commented out all mentions of this lib in the codebase, and the build worked.
Now, when running yarn android for development, we have this:
1.Error: No Firebase App '[DEFAULT]' has been created - call firebase.initializeApp(), js engine: hermes
2.Invariant Violation: "updatedapp" has not been registered. This can happen if: Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
3.A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called., js engine: hermes
Among these errors, the real issue is number 2, where the official app name is com.Updatedapp, and I'm working with com.updatedapp (I didn't notice this in the early steps of the update), and to solve this, I followed this post (https://stackoverflow.com/questions/74774494/how-to-change-android-package-name-in-react-native-0-70-and-above)[https://stackoverflow.com/questions/74774494/how-to-change-android-package-name-in-react-native-0-70-and-above]
After updating the package name in these locations, I had many problems involving updatedapp.BuildConfig. I need to find out where it is or how to generate it. I tried com.updatedapp.BuildConfig in MainApplication.java, and ./gradlew assembleRelease worked. Now, when running the application with yarn android, I get this message:
- Invariant Violation: "updatedapp" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
After much research, I focused on the end of this post https://github.com/wix/react-native-navigation/issues/5520, changing the names in MainActivity.java
Faith begins to be shaken
It's already the beginning of the fourth day debugging this; the focus is no longer the same.
With no options and knowing that I had to solve this packageName issue, I decided to look at the code of the production app and compare it with the app I was updating.
I found a difference in MainActivity.java in my version, where it was set as "updatedApp" but it was just supposed to be "main": java
@Override
protected String getMainComponentName() {
return "main";
}
I had to add another block in andrid/app/build.gradle because it was generating bundles with debug configurations, and as my app is signed directly by the store and not a physical key, I created another block of configurations for production bundles.
And it worked. 🙌
Time to submit the app to the Store
Yes, there were more errors. The store still pointed to an error: "Cannot release this version because it does not allow existing users to update to the new app packages."
To solve this, I just had to see which was the last version of the app I had submitted to the store and correct it by putting a higher version in build.gradle.
Now, it's finally resolved!
Conclusion
This journey took 4 and a half days, so never underestimate an update. I hope I managed to show the not-so-glamorous side of programming and how the resolution of each problem emerged.
See you soon, Cheers!