Environment Variable Setup for iOS, Android, React Native, Flutter

Builds fail due to incorrect environment values, and releases break at the worst possible moment. We set up mobile app environment variables turnkey: separate environments, eliminate manual edits, and cut build preparation time by more than half. Let's discuss your task — we'll come back with an estimate and a plan.

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Environment Variable Setup for iOS, Android, React Native, Flutter
Simple
from 1 day to 3 days

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a mobile application for FEEDME
    Development of a mobile application for FEEDME
    971
  • Development of a mobile application for XOOMER
    Development of a mobile application for XOOMER
    869
  • Development of a mobile application for RHL
    Development of a mobile application for RHL
    1289
  • Development of a mobile application for ZIPPY
    Development of a mobile application for ZIPPY
    1143
  • Development of a mobile application for Affhome
    Development of a mobile application for Affhome
    1076
  • Development of a mobile application for the FLAVORS company
    Development of a mobile application for the FLAVORS company
    677

Why builds break on environment variables

An application runs reliably on the developer's machine, but fails in the build with a blank screen or an authorization failure — almost always the cause is the mobile app's environment variables.

Locally, the values are pulled from an uncommitted file that only the code's author has. In the ios android build that file is missing, an empty string or a default value is substituted — and the configuration falls apart at the startup stage rather than at compilation.

The classic scenario: the service address and keys are hardcoded directly in the source for a specific environment. The moment you switch from development to a test environment, the app hits the production server or gets rejected due to a mismatched identifier.

Configuration errors surface only after release, when reproducing them off-device is nearly impossible.

A separate and more costly problem is secrets in the repository. Payment system keys, analytics and push service credentials sit in the commit history in plain text. The leak is discovered after the fact, and rotating a key requires a rebuild and re-publishing to every store.

The root cause is that different environments — development, test, pre-production, production — are not separated at the build level. Values are substituted manually, depend on who is running the build and from which machine, and are not validated before deployment.

Let's break down how this gets fixed: a single source of values, automatic substitution per environment, and protecting secrets from ending up in the repository.

What managed environment configuration provides

Configuration management eliminates the most expensive class of errors in mobile development — when an app goes to the store with a test environment URL or a key from someone else's environment.

When values are moved out of the code into separate profiles, the build stops depending on what the developer remembered at the moment of commit: the configuration is versioned alongside the code, validated at build time, and cannot "leak" between environments.

Build speed increases because switching between environments is a profile change, not editing source files and recompiling. The same artifact is built with different sets of parameters, the cache is not reset, and the time to prepare a release branch is cut severalfold.

Reproducibility delivers a predictable result: a build assembled today will repeat tomorrow without "but it works on my machine."

The reduction in failures comes from the same place — the absence of manual edits before publishing.

Release transparency emerges when you can see which values went into a specific version and who changed them: incident investigation takes minutes instead of hours of searching through commit history.

A separate benefit is onboarding: a new engineer spins up an environment with a single command, without begging for access or assembling a config from chat messages.

In total, managed environment configuration delivers a measurable effect: fewer failed releases, a shorter cycle from commit to store, predictable app behavior on every environment.

This is not a one-time setup but part of the release process that we establish from the first sprint.

Approaches to storing and injecting values

Values enter a build through three fundamentally different paths, and the choice between them determines what happens when the repository leaks, the environment changes, or a release is rolled back.

In practice, they are combined: some parameters sit openly in configuration files, some are injected at build time, and secrets are moved to protected vaults.

Option When it fits Limitations
Configuration files in the repository Public parameters: environment addresses, feature flags, application identifiers Secrets in version control history remain forever; changing a value requires an edit and a new commit
Build system variables Different development environments from a single code branch, parameters that depend on the environment Values are visible in build logs; with a manual build it is easy to inject the wrong environment
Protected vaults Signing keys, tokens for external services, credentials for payment integrations The build agent needs access to the vault; local builds require separate configuration

The key rule is that secrets do not end up in the application artifact.

Anything hardcoded into a build can be extracted from it through reverse engineering, so tokens that grant access to server-side resources are kept on the service side, and only public identifiers are left in the application.

Value injection is tied to the environment: the build agent receives a set of parameters for a specific environment and bakes them in at the compilation stage.

Then a single code branch produces builds for development, testing, and production without manual file editing — and divergence between environments stops being a source of errors.

Rollback is handled separately: if a value changes without a rebuild, it is moved to a remote configuration that the application reads at startup.

This speeds up incident response but adds a dependency on the availability of the configuration service — and this trade-off should be factored in from the start.

How we configure mobile app environment variables

Configuring environment variables is not a one-time file edit, but a managed process with a verifiable result. Below is how we run it from audit to handover, so that the configuration does not diverge between builds and does not break a release.

  1. Configuration audit. We gather all the places where server addresses, keys, and flags are currently hardcoded: build files, schemes, native modules, CI scripts. We record which values are duplicated, where hardcoded strings remain, and which branches already diverge from each other.
  2. Environment scheme. We define the set of environments — development, testing, pre-production, production — and a single list of variables for each. We agree on the rules: what can be changed without a rebuild, what requires a new version, and which values are secret and must not end up in the repository.
  3. Variable setup. We establish a single source of values and connect it to each platform — iOS, Android, React Native, Flutter. We move secrets into a secure vault and leave only references to them in the code, so that keys do not leak through commit history.
  4. Build verification. We run the build on each environment and verify that the app starts with the correct addresses and flags. We separately check switching between environments without manual file edits and rolling back to the previous configuration.
  5. Documentation handover. We deliver the environment scheme, a list of variables with their purpose, instructions for adding new values, and the procedure for handling an incident. The client's team then maintains the configuration independently.

This order eliminates the class of errors where a test build goes to production with someone else's keys. Describe your task — we will come back with an estimate and a work plan.

Configuration artifacts and regulations

Environment configuration lives not in chat threads or in the release engineer's head, but in a set of files that can be opened, compared, and handed over to another team.

Below is a typical package that the client receives after setting up environment variables for iOS, Android, React Native, and Flutter.

  • Configuration files by environment — separate sets of values for development, testing, and production: service addresses, access keys to external systems, feature flags. Secrets are not stored in the repository: they are injected at build time from a secure vault.
  • Environment map — a diagram showing which stand belongs to which environment, which services it uses, and how values flow from one environment to another. With it, a new engineer gets up to speed in an hour, not a week.
  • Access policies — who on the team can modify which environments, which actions require confirmation from a second engineer, how access to secrets is granted and revoked. Permissions are separated by role, not handed out to "anyone who needs it."
  • Release procedure — a step-by-step order: how to add a new variable, how to test it on the test environment, how to roll it out to production without stopping the service. What to do during a rollback is described separately.
  • Variable documentation — a table with all parameters: purpose, allowed values, the environment where it applies, who is responsible for keeping it up to date. Discrepancies between code and documentation are caught at the review stage.
  • Configuration validation scripts — automated checks that prevent building an app with an empty or incorrect value. The error surfaces before release, not for the user.
  • Handover instructions — what needs to be done and in what order so that the client's team can manage the configuration independently going forward: access, entry points, order of changes.

The package remains workable when the contractor changes or the team expands: values are not hardcoded, and environments are described in such a way that they can be reproduced from scratch.

Describe your task — we will come back with an estimate and a plan for the set of artifacts for your project.

Case study: faster builds and fewer failures

A React Native project came to us: two builds for iOS and Android, four environments — development, testing, pre-production, and production.

The configuration lived in a single .env that was edited by hand before every build, and access keys to services were hardcoded right into the source code.

A mistake in a single key meant the app went to the store with test-stand settings — and rolling back took hours of manual work.

What we changed

We separated configuration by environment and moved it out of the code: each build gets its own set of values at compile time instead of being swapped by hand.

Secrets were moved into a secure vault and wired into the build process — only references to them remained in the repository, not the keys themselves.

We added a check: if a required variable is missing for the selected environment, the build stops immediately instead of crashing on a tester's device.

The result in numbers

Metric Before After
Full build time ~18 minutes ~7 minutes
Failures due to incorrect configuration 3-4 per month 0 per quarter
Manual configuration edits before every build not required

The build got faster thanks to dependency caching and eliminating repeated value substitution. The class of failures tied to human error when switching environments disappeared entirely — the environment is now determined automatically from the branch.

We applied a similar approach on a Flutter project: there we separated configuration through dedicated build schemes, and the team stopped having to keep track of which file to edit before a release.

How do environment variables differ for iOS and Android?

The differences start with where a value can even live. In iOS, configuration traditionally lives in Info.plist and in build scheme settings: the same code is built for different environments by switching the scheme, and values are substituted at build time.

In Android, the equivalent is BuildConfig and res/values resources, where the build variant defines its own set of constants.

Hence the first practical divergence: on iOS, secrets are more conveniently kept outside the repository and injected at build time, while on Android some values historically end up directly in the artifact and remain readable after unpacking.

The second difference is the moment of substitution. iOS gravitates toward values hardcoded at compile time: you cannot change the environment without rebuilding, but the release behavior is predictable and does not depend on what is stored on the device.

Android allows configuration to be read at runtime — from resources, system properties, or a remote source.

This is more flexible for gradual feature rollouts, but it adds a class of failures: the app starts with an empty or outdated value and crashes at runtime rather than at build time.

The third is secrets management. Neither Info.plist nor BuildConfig protects keys: both formats are parsed from the finished package. That is why on both platforms secrets are moved to the server side, and only public identifiers are left in the app.

The only difference is where a developer looks out of habit, and how easily that habit leads to a leak.

Cross-platform solutions smooth over the syntax but do not eliminate the differences: the configuration layer still compiles down to each platform's native mechanisms.

That is why configuration is designed once — with a single set of variable names and an explicit separation into public and server-side — and then laid out across native stores.

This way, builds for ios and android remain predictable, and changing the environment does not turn into editing code.

Common technical concerns

Environment variables are the area where either security or the build most often breaks. Below are the questions asked on almost every project: where to store values, how to migrate to a new scheme without downtime, and who is responsible for configuration after release.

Are secrets in environment variables safe?

Environment variables are transport, not storage. We keep keys and tokens in a secure vault, and only short-lived values issued for a specific environment make it into the build and onto the device.

On top of that, we separate the perimeters: test and production secrets do not overlap, each has its own access scope. That way a build leak does not expose the production perimeter.

How do you migrate to a new scheme without halting releases?

We run the migration in parallel: the new variable scheme is brought up alongside the old one, the app reads both and gradually switches over. Rollback means reverting to the previous set of values, with no rebuild and no re-publishing to the stores. This way the transition takes days, not a quarter, and does not block current releases.

What about configuration after release — who maintains it?

Configuration lives as code: changes go through review, are versioned, and are rolled out across environments automatically. Adding a new environment or changing a service address is an edit to a single file, not a manual build for each platform.

We hand over the scheme, the rules, and the instructions to your team so that maintenance does not depend on us.

Will this work the same on iOS, Android, React Native, and Flutter?

Yes, the scheme is shared: a single set of environments and rules, while platform differences are handled at the build level. The developer describes the values once, and the builder itself substitutes the ones needed for a specific platform and environment.

This eliminates discrepancies where everything works in testing but in the store the app points to the wrong place.

If your scenario is not on the list — describe the task, and we will get back to you with an estimate and a plan.

Let's discuss your task

The discussion starts not with a price list, but with your project: which platforms are in scope, how many environments need to be separated, and how the build is currently set up.

Based on these inputs, our engineers prepare an estimate and a work plan — with stages, timelines, and areas of responsibility. Then you decide whether we move forward together or not.

To make the conversation substantive, it helps to have a few things on hand right away:

  • a list of platforms and target environments — where the app already lives and where it is only planned;
  • how keys and build parameters are currently stored: in the repository, in the CI system, or passed manually;
  • access to repositories, build systems, and app store consoles;
  • a description of the current release process — who builds the release and how, and how long it takes;
  • known constraints: security requirements, approvals, working with contractors;
  • the contact of the person responsible for the mobile direction on the business side.

Based on this data, we come back with an estimate and a plan: which environment variables need to be created, how to separate configurations between environments, what will go into secure storage, and what will remain in the open.

Separately, we discuss how rollback will be organized and what happens if the configuration diverges between platforms.

If you already have work in progress — configs, build scripts, a draft of the environment scheme — bring them along, and we'll review them on the spot. That way the estimate will be more accurate and the plan more realistic.

Describe the task in whatever format is convenient: a short message, a document, or a 30-minute call.