Skip to content

🚩 Feature Flags ​

Mobile feature flags are booleans served by Firebase Remote Config (lib/feature-flags/).

Flag Registry (lib/feature-flags/flags.ts) ​

Every flag must be declared in FEATURE_FLAG_DEFAULTS before use. The key must exactly match the key in the Remote Config console.

ts
export const FEATURE_FLAG_DEFAULTS = {
  in_app_camera_capture: false,
} as const satisfies Record<string, boolean>;

export type FeatureFlagName = keyof typeof FEATURE_FLAG_DEFAULTS;

Defaults must be "safe off" β€” the app must work correctly when the flag is false.

Initialization (lib/feature-flags/remote-config.ts) ​

FeatureFlagsProvider calls initRemoteConfig() once on app start. It fetches and activates remote values; on any failure (e.g. no network) it falls back to the in-code defaults β€” it never throws.

Cache interval:

  • Production: 1 hour
  • Dev / Staging: 0 (always fetch fresh)

Reading Flags ​

tsx
import { useFeatureFlag } from '@/hooks/use-feature-flag';

// Single flag (preferred)
const inAppCameraEnabled = useFeatureFlag('in_app_camera_capture');

// Full flag map
import { useFeatureFlags } from '@/hooks/use-feature-flags';
const flags = useFeatureFlags();

TypeScript will error on unknown flag names.

One Template, Shared With Web ​

Each Firebase project (tell-ia-dev, tell-ia-staging, tell-ia-production) has a single Remote Config template, shared by the mobile app and the web app (apps/agri-frontend/src/lib/remote-config/remote-config.ts, e.g. the app_promo_* keys). Mobile ignores keys it does not declare and logs one dev warning listing them β€” that is expected, not a signal to delete them.

Adding a Flag ​

  1. Add the key + default to FEATURE_FLAG_DEFAULTS in lib/feature-flags/flags.ts
  2. Create the key in Remote Config in all three projects β€” a key missing from staging leaves the feature unreachable for QA
  3. Use useFeatureFlag('your_flag_key') in the component
  4. Guard the new behavior: if (!isEnabled) return <OldBehavior />

Removing a Flag ​

Store builds on an older runtime fingerprint never receive the OTA that removes a flag, so they keep reading the console key. The in-code default is false, so deleting a key that is true turns the feature off for those users.

  1. Code first (JS-only, OTA is fine): delete the key from FEATURE_FLAG_DEFAULTS, inline the "on" behavior, and drop flag-off tests and Maestro branches.
  2. Leave the console key at its current value.
  3. Delete the console key from all three projects only once Sentry release adoption shows the older builds have drained.

To edit a template from the CLI, pull it first (firebase remoteconfig:get --project tell-ia-<env> -o template.json), edit, then publish with firebase deploy --only remoteconfig --project tell-ia-<env> using a firebase.json of {"remoteconfig":{"template":"template.json"}}. The console shows unpublished edits as "Just now" β€” check firebase remoteconfig:versions:list for what is actually live.