152

I am using React native with Android. How can I update version number in the app? As I am getting this error.

I am generating file as per this url https://facebook.github.io/react-native/docs/signed-apk-android.html

I have tried modifying AndroidManifest.xml file, but after I build it, that file gets automatically modified back.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.facebook.react"
    android:versionCode="1"
    android:versionName="1.0" >

Here, I modified the XML:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.facebook.react"
    android:versionCode="2"
    android:versionName="1.1" >

After, build file automatically changes back.

enter image description here

sparkyShorts
  • 630
  • 9
  • 28
Praveen Prasad
  • 1,863
  • 3
  • 13
  • 13
  • 1
    android:versionCode="2" mean whenever you want to upload apk on play store that is necessary to increase version code & version code you can keep whatever you want doesn't impact – Ajinkya Mar 10 '16 at 18:48
  • doesn't work, I have already done it. I have corrected my question. – Praveen Prasad Mar 10 '16 at 18:49

8 Answers8

287

You should be changing your versionCode and versionName in android/app/build.gradle:

android {

    defaultConfig {

        versionCode 1
        versionName "1.0"
        
        {...}
    }

    {...}
}

Note that versionCode has to be in an integer that is larger than the ones used for previous releases while versionName is the human readable version that may be shown to users.

DysphoricUnicorn
  • 495
  • 7
  • 16
Joseph Roque
  • 5,066
  • 3
  • 16
  • 22
  • Thanks, I myself saw that file multiple times, but just missed that part. – Praveen Prasad Mar 11 '16 at 04:56
  • 4
    I found the solution in the file that you pointed to, but it was actually slightly further down. There was a section that started with **applicationVariants** and in there the **output.versionCodeOverride** was getting set, which did as the name suggested and overrode the one at the top of the file. – AidenMontgomery May 18 '16 at 12:01
  • What about in AndroidManifest.xml do we need to update that? – Noitidart Jun 06 '17 at 02:45
  • 2
    @Noitidart if you're building with Android Studio and Gradle, changing it here will be enough. It will override anything you put in AndroidManifest.xml – Joseph Roque Jun 06 '17 at 20:20
  • 2
    If I want my version to be "2.2" should I set versionCode to `2.2`? I don't understand `versionCode` :( – Noitidart Nov 14 '17 at 23:53
  • 20
    @Noitidart `versionCode` is a value that's meant for Google/you. When you upload to Google Play, it expects `versionCode` to be greater than the previous `versionCode`, and also unique for every uploaded file. Personally, I just manually increment `versionCode` by one each time I prepare an upload to Google Play. Other people automate it to increment based on the git commit, or other factor. `versionName` is what you would change to "2.2" so that your users will see that version number when they update/download your app. – Joseph Roque Nov 15 '17 at 02:27
  • Thank you sir very much for such an awesome explanation. @JosephRoque – Noitidart Nov 15 '17 at 02:29
  • must versionCode be a integer? 1.0.1 fails for me – otto Apr 29 '18 at 00:38
  • 4
    @KTWorks yes, versionCode must be an integer. versionName can be set to `1.0.1` and will display that value to users. – Joseph Roque Apr 29 '18 at 15:08
110

@Joseph Roque is correct, you need to update the version numbers in android/app/build.gradle.

Here's how I automate this and tie it into the package's version in package.json and git commits.

In android/app/build.gradle:

/* Near the top */

import groovy.json.JsonSlurper

def getNpmVersion() {
    def inputFile = new File("../package.json")
    def packageJson = new JsonSlurper().parseText(inputFile.text)
    return packageJson["version"]
}
/* calculated from git commits to give sequential integers */
def getGitVersion() {
    def process = "git rev-list master --first-parent --count".execute()
    return process.text.toInteger()
}


......


def userVer = getNpmVersion()
def googleVer = getGitVersion()

android {
...
    defaultConfig {
        .....
        versionCode googleVer
        versionName userVer

        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }

Notes:

  • It's important that versionCode is an integer - so we can't use semantic versioning here. This is used on the play store to tell which versions come after others - that's why it's tied to git commits in getGitVersion

  • versionName however is shown to users - I'm using semantic versioning here and storing the real value in my package.json. Thanks to https://medium.com/@andr3wjack/versioning-react-native-apps-407469707661

danielbeard
  • 9,120
  • 3
  • 44
  • 58
tgf
  • 2,977
  • 2
  • 18
  • 29
  • 6
    Andrew Jack discusses a very similar method, and a method for iOS in his Medium article: https://medium.com/@andr3wjack/versioning-react-native-apps-407469707661#.ky7l2lys7 . It is a great read for people wanting to keep their versions matching with their builds. – DBrown Mar 17 '17 at 03:59
  • Does it mean that every time I used **git commit** the version changes incrementally? And which update type is incremented? I mean, will it start in the patch number? – Edison Pebojot Mar 02 '21 at 11:28
  • 1
    @EdisonPebojot Yes, though only one of the versions will change. There are two version types - the versionCode which must be incremental and is based on number of commits. And the versionName which is taken from your package.json can be a string and is visible to the user. You may want to read this answer: https://stackoverflow.com/a/10269683/1760776 for more details – tgf Mar 02 '21 at 22:23
  • 1
    Andrew Jack's article on Medium has been deleted. Here's his blog post on the topic, though: https://blog.andrewjack.uk/versioning-react-native-apps. – Hal Mueller Dec 13 '21 at 03:51
  • 1
    Need change master to main `def process = "git rev-list main --first-parent --count".execute()` – robersonfox Jan 26 '22 at 23:47
  • I keep getting `../package.json (No such file or directory)`. I've tried changing to `../../` too, to no avail. – Chris Edwards Aug 10 '23 at 16:15
48

For those wanting to automate this, and have iOS at the same time, you can use react-native-version to set the version numbers.

All you need to do is update your version number inside the package.json file and run the following:

$ npx react-native-version --never-amend

[RNV] Versioning Android...
[RNV] Android updated
[RNV] Versioning iOS...
[RNV] iOS updated
[RNV] Done
✨  Done in 0.39s.

I hope this can help others.

Francois Nadeau
  • 7,023
  • 2
  • 49
  • 58
  • 2
    If you have ejected from expo, make sure the app.json is deleted otherwise the android and ios files will not get updated. – Bjorn Reppen Feb 03 '21 at 16:50
  • 1
    @bjorn-reppen Deleting app.json in Bare Workflow Expo projects is not the best solution, as App.json is still used by Expo (Updates for example) The issue is being discussed here: https://github.com/stovmascript/react-native-version/issues/105 I patched react-native-version 4.0.0 as a temporary workaround until it gets fixed. – ChrisW Jul 16 '21 at 20:08
4

I had the same problem and I checked all the above answer, I had a made a silly mistake because of which nothing worked for me. Just in case any of you do same mistake as mine try this.

  1. Version can be a decimal number like 1.0 or 1.0.1 etc
  2. But VersionCode cannot be decimal number It should be 1,2,3 etc and not 1.1 or 2.2

So in project/app/build.gradle

android {
defaultConfig {
    versionCode 1 // do not use decimal number here
    versionName "1.0" // you can use decimal number here.
    {...}
}
{...}
}
Vasanth
  • 560
  • 1
  • 5
  • 25
2

Set the versionCode under android in app.json:

{
  "expo": {
    "name": "App Name",
...
    "android": {
      "package": "com.app.name",
      "permissions": [],
      "versionCode": 2
    }
  }
}

ref:https://docs.expo.io/versions/latest/workflow/configuration/#versioncodeversion-number-required-by-google-play-increment-by-one-for-each-release-must-be-an-integer-httpsdeveloperandroidcomstudiopublishversioninghtml

oOEric
  • 1,069
  • 1
  • 10
  • 25
0

If someone is facing

wrong version code eg - 31284

Then make sure to not use SeparateBuildPerCPUArchitecture in android/app/build.gradle

def enableSeparateBuildPerCPUArchitecture = false

and

to update the version code and name change in android/app/build.gradle:

android {

defaultConfig {

    versionCode 1
    versionName "1.0"

    {...}
}

{...}
}
kvadityaaz
  • 1,441
  • 1
  • 16
  • 23
0

What @tgf has is good for Android, but I wanted ios as well. The default Info.plist sets CFBundleShortVersionString to $(MARKETING_VERSION), which is the same as versionName in android/build.gradle, and CFBundleVersion is set to $(CURRENT_PROJECT_VERSION), which is the same as versionCode in android/build.gradle. These are defined in the project.pbxproj in ios/AppName.xcodeproj/. Here is a prerelease script that can update the xcode file. If you have modifications that have no been committed yet, it will add 1 to the build number so that building without any changes will not result in a file change.

yarn add glob --dev
    "ios-update-version": "node scripts/iosUpdateVersion.js",

Use pre scripts to run this command.

scripts/iosUpdateVersion.js:

const { globSync } = require('glob');
var fs = require('fs');
const { execSync } = require('child_process');
const APP_VERSION = require('../package.json').version;
const GET_COMMIT_COUNT = 'git rev-list master --first-parent --count';

let BUILD_NUMBER = 0;

if (execSync('git status --porcelain').length) {
    console.log('increasing build number by one to include untracked changes');
    BUILD_NUMBER++;
}

const response = execSync(GET_COMMIT_COUNT).toString();
BUILD_NUMBER += Number.parseInt(response.trim());
// android (taken care of in build.gradle)
// versionCode googleVerver  // BUILD_NUMBER
// versionName userVer      // APP_VERSION
// ios
// CFBundleVersion CURRENT_PROJECT_VERSION = 1;            // BUILD_NUMBER
// CFBundleShortVersionString MARKETING_VERSION = 1.0;     // APP_VERSION
const plist = '/ios/SplitTheTank/Info.plist'
const xcodeprojs = globSync('ios/*.xcodeproj');
if (xcodeprojs.length === 0) {
    throw 'Could not find any xcodeproj folder'
}
const pbxproj = `${xcodeprojs[0]}/project.pbxproj`;
const data = fs.readFileSync(pbxproj, 'utf8');

let result = data.replace(/(CURRENT_PROJECT_VERSION = )(.*);/g, `$1${BUILD_NUMBER};`);
result = result.replace(/(MARKETING_VERSION = )(.*);/g, `$1${APP_VERSION};`);
fs.writeFileSync(pbxproj, result, 'utf8');
Elijah
  • 1,814
  • 21
  • 27
-1

If you're using expo and getting this issue, go to app.json and change the version to a higher number.

{
  "expo": {
    "name": "nameofapp", // btw dont copy this
    "slug": "appslug",   // btw dont copy this
    "version": "1.0.0",  // here is where you change the version
    ...
    ...
    ...
  }
}

You need to also change the version in package.json

{
  ...
  "name": "appname",  // btw dont copy this
  "version": "2.0.0", // here is where you change the version
  ...
  "android": {
    "versionCode": 2,
    ...
  }
  ...
}
Atif Khan
  • 206
  • 1
  • 10