AppForShare

How to tell testers a new build is ready, from inside the app

· 9 min read

How to tell testers a new build is ready, from inside the app

You ship a fix on Tuesday, send the link, and on Thursday a tester reports the same bug again. They never installed Tuesday's build. This is the most ordinary problem in mobile testing, and it gets worse the more often you ship. The fix is to let the test build itself notice that a newer build exists and offer it, instead of relying on testers to read every message.

This guide explains why testers stay on old builds, compares the ways to prompt them from inside the app, shows how to compare build numbers correctly, and covers the one rule that matters most: the check belongs in test builds only.

Why testers stay on old builds

  • The message arrives once. An email or chat message about a new build is easy to miss, and nobody goes back to look for it a day later.
  • The old build still works. Nothing tells the tester it is out of date, so they keep using the icon on their home screen.
  • The install link was scanned once. Field testers and client stakeholders often install from a QR code on day one and never see the link again.
  • Testers do not know what changed. Without release notes in front of them, there is no reason to update.

The result is bug reports against code that is already fixed, and time spent asking people which version they have. Showing the version and build number in the app helps (see our test build distribution best practices), but it does not make anyone update.

The options, compared honestly

TestFlight automatic updates (iOS only)

If your testers install through TestFlight, the problem is mostly solved for you. Since TestFlight 3, testers can turn on automatic updates, and the TestFlight app installs new builds as they become available and notifies the tester. There is nothing to add to your app.

The limits are the usual TestFlight ones: it covers Apple platforms only, testers need the TestFlight app and an Apple Account, builds for external testers go through Apple's beta review, and each build expires after 90 days. Automatic updates are also a tester setting, so you cannot force them on. If those limits are why you use install links instead, read TestFlight alternatives.

Firebase App Distribution in-app alerts

Firebase App Distribution has an SDK for iOS and Android that checks for a newer build and shows an alert. Testers enable alerts by signing in with their Google account, and on Android the full SDK can download a new APK in the background and prompt the tester to install it (for an AAB build, it sends the tester to Google Play). As of late 2026 Firebase still labels these SDKs as beta, which means the API can change and there is no SLA. The in-app alerts are not available for macOS, Mac Catalyst, tvOS or watchOS targets, and they cannot be tested on a simulator.

Firebase is also clear about store builds: the full Android SDK contains self-update code that may be considered a Google Play policy violation even if it never runs, so it must be kept out of Play builds. It makes sense if your app already uses Firebase. If it does not, adding an SDK and a Google sign-in for testers just to show a prompt is a lot. We compare the wider product in Firebase App Distribution alternatives.

Google Play in-app updates API

The Play in-app updates API (part of the Play Core libraries) offers two flows: flexible, where the update downloads in the background while the app stays usable, and immediate, a full screen flow that blocks the app until it updates and restarts. It runs on Android 5.0 and later, on phones, tablets and ChromeOS devices.

It only works through Google Play. The update comes from Play, so it applies to apps installed from Play, including internal and closed testing tracks. It does nothing for an APK a tester sideloaded from a link. If your testers are on a Play testing track, use it there. If they install from a link, you need something else.

Your own check against a version endpoint

The simplest approach that works for sideloaded builds on both platforms: the app asks a URL for the newest build number, compares it with its own, and if a newer one exists, opens the install page. No SDK, no tester sign-in. You need three things:

  • An HTTPS endpoint that returns the newest build per platform, updated whenever you hand out a build.
  • A comparison that is correct for your platform's build numbers.
  • An install page to send the tester to. The app cannot install anything itself on iOS; it opens Safari and the tester taps install. On Android it can open the APK link in the browser and let the system installer take over.

The work is in keeping the endpoint honest. If CI uploads a build but the endpoint still lists the old one, testers see nothing. If you roll back, the endpoint has to roll back too.

How to compare versions correctly

Compare build numbers, not version strings. The version (CFBundleShortVersionString on iOS, versionName on Android) is a label for people, and it often stays the same across many test builds of one release. The build number changes on every build you hand out, so it is what tells you a tester is behind.

  • iOS, CFBundleVersion: a string of up to three period separated integers, such as 118 or 2.4.118. Compare it numerically, part by part. A plain string comparison says "9" is newer than "10". In Swift, compare(_:options: .numeric) does the right thing.
  • Android, versionCode: a positive integer. Parse it and compare as a number. Android will not install a lower versionCode over a higher one without an uninstall, so it has to go up on every build anyway.
  • Treat "different" carefully. Prompt only when the server build is higher. If you also want rollbacks to reach testers, prompt when the server build is lower too, but say so in the message, and remember that on Android a lower versionCode needs an uninstall first.
  • Fail quietly. No network, a timeout or an unexpected response should mean no prompt, not an error dialog.

UX that testers do not hate

  • Do not block the app. A tester in the middle of reproducing a bug should be able to dismiss the prompt and finish. A banner or a dismissible alert is enough.
  • Show the release notes. "Build 118: fixes the login crash" gets a tap. "A new version is available" gets ignored.
  • Do not nag. Check when the app comes to the foreground, not on a timer, and after a dismiss, wait a few hours or until the next build before asking again.
  • Say what installing means. On Android, a build signed with a different key than the one installed needs an uninstall first, which wipes local data. Tell testers before they lose a logged in session.
  • Remember ad hoc rules on iPhone. The new build installs only if the tester's device UDID is in its provisioning profile. Prompting someone to install a build their device is not in leads to a confusing failure. See Ad Hoc device registration.

Never ship the check in store builds

This is the part teams get wrong. A store build must update through its store, and both stores say so.

  • Google Play: the Device and Network Abuse policy says an app distributed via Google Play may not modify, replace or update itself by any method other than Google Play's update mechanism, and may not download executable code from a source other than Google Play. A prompt that sends users to download an APK from your server breaks that.
  • App Store: guideline 2.5.2 says apps may not download, install or execute code that introduces or changes features of the app, including other apps. A store build that points users to an ad hoc install page would not work for them anyway, since their devices are not in your profile, and it invites a rejection.

Put the check behind a build flag that only your test configuration sets, for example a Swift compilation condition in your ad hoc configuration or a BuildConfig field set only in your test build type or flavor on Android. Do not rely on a runtime flag alone: Firebase's own note about Play is that self-update code can be a problem even if it never runs. Then confirm the release build does not contain it.

Doing it with AppForShare channels

On AppForShare, the version endpoint already exists. Builds go into channels, such as Beta and Live, from the dashboard or from CI. Each channel has a stable link and QR code that opens the newest build in it (see Beta and Live channels), and since November 2026 each channel also has a public JSON address your test build can read:

GET https://appforshare.io/api/c/YOUR_CHANNEL/latest?platform=android

{
  "channel": "Beta",
  "platform": "android",
  "version": "2.4.0",
  "build": "118",
  "releaseNotes": "Fixes the login crash",
  "installUrl": "https://appforshare.io/i/AbC123",
  "channelUrl": "https://appforshare.io/c/YOUR_CHANNEL",
  "publishedAt": "2026-11-01T10:00:00.000Z"
}
  • build is the iOS CFBundleVersion or Android versionCode, so you compare it with the same value from the installed app.
  • Use platform=ios or platform=android. A channel with no build for that platform answers 404, which your code should treat as "no update".
  • releaseNotes is null when the build has a password, so the notes are not exposed on a public address.
  • The answer can be cached for up to 60 seconds, and it allows requests from any origin.
  • Putting an older build back into the channel is what apps then see, so a rollback reaches testers through the same check.

There is no SDK. The update check docs have short snippets for Swift, Kotlin, Flutter and React Native that read this address, compare build numbers and open installUrl. You find your channel's address in the dashboard under Projects, Testing, Update check. The tester still taps to install, and on iPhone the new build still needs their device in its profile.

The update check is part of Pro and Team, the plans with channels (see pricing). It is meant for test builds only: keep it out of App Store and Google Play builds, for the reasons above. More on the feature at in-app update check.

Keep reading

App Distribution Platform · · 9 min read

AppForShare.io vs Competitors - A Comparative Analysis

For small teams and startups, selecting a mobile app testing platform is a critical crossroad. This choice is more than a mere selection: it’s a strategic decision that directly impacts the...