Fluxy
Fluxy Plugins

OTA Engine (Over-The-Air)

Real-time application updates and remote configuration without store redeployment.

OTA Engine (Over-The-Air)

The fluxy_ota module provides high-level orchestration for remote manifests, asset synchronization, and the "Big Red Button" kill-switch for production safety.

[GUIDE] Industrial Step-by-Step

1. Installation (via CLI)

Add the OTA module using the Fluxy CLI to maintain architectural integrity.

fluxy module add ota

2. Managed Boot Sequence

Ensure your main.dart is configured with the mandatory three-step boot sequence.

import 'package:fluxy/fluxy.dart';
import 'core/registry/fluxy_registry.dart'; 

void main() async {
  await Fluxy.init();
  Fluxy.registerRegistry(() => registerFluxyPlugins()); 
  Fluxy.autoRegister(); // Boots environment core
  runApp(MyApp());
}

3. Usage (Unified API)

Access the module through the direct Fx.platform.ota helper.

void checkForUpdates() async {
  // 1. Fetch and apply remote manifest
  await Fx.platform.ota.update("https://cdn.myapp.com/latest_v3.json");
  
  // 2. Access cached JSON assets
  final seasonalConfig = await Fx.platform.ota.getJson("seasonal_campaign.json");
  if (seasonalConfig != null) {
     print("Campaign Active: ${seasonalConfig['title']}");
  }
}

Remote Kill-Switch (Safety)

One of the most powerful features of the OTA engine is the ability to remotely disable specific platform modules to neutralize production crashes.

{
  "version": 5,
  "disabled_plugins": ["fluxy_biometric"],
  "assets": { ... }
}

When this manifest is synchronized, Fluxy will prevent the fluxy_biometric module from initializing on the next boot, effectively stopping an "Infinite Crash Loop" caused by a specific OS version or hardware incompatibility.


The Master OTA Implementation

In a professional application, OTA is used for more than just code updates; it's used for dynamic feature targeting and asset management. Here is a complex "Boot Loader" demonstrating best practices for OTA orchestration.

class AppBootController extends FluxController {
  final isSyncing = flux(false);
  final updateStatus = flux('Initializing...');

  @override
  void onInit() async {
    super.onInit();
    await _performRemoteSync();
  }

  Future<void> _performRemoteSync() async {
    isSyncing.value = true;
    updateStatus.value = 'Checking for architectural updates...';

    try {
      // 1. Trigger the OTA update cycle
      // This automatically handles versioning and asset caching
      await Fx.platform.ota.update("https://api.fluxy.io/v1/manifest");
      
      // 2. Retrieve dynamic configuration for the current session
      final remoteConfig = await Fx.platform.ota.getJson("session_config.json");
      
      if (remoteConfig != null && remoteConfig['force_logout'] == true) {
        // Handle emergency remote logout
        await Fx.platform.auth.signOut();
        Fx.toNamed('/login');
      }

      updateStatus.value = 'Environment Ready';
    } catch (e) {
      updateStatus.value = 'Local Mode (Sync Failed)';
      Fx.log.fatal("OTA Sync interrupted", error: e);
    } finally {
      isSyncing.value = false;
    }
  }

  // Example of using OTA assets in UI
  Widget buildSeasonalBanner() {
    return FutureBuilder<Map<String, dynamic>?>(
      future: Fx.platform.ota.getJson("banner_v1.json"),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return const SizedBox.shrink();
        
        final data = snapshot.data!;
        return Fx.box()
          .bg(Fx.hex(data['color']))
          .p(16)
          .child(Fx.text(data['text']).font.white());
      },
    );
  }
}

By centralizing all remote knowledge under the Fx.platform.ota helper, you ensure that your application can adapt to production issues in real-time without requiring a single line of client-side code change.

On this page