remote_config_codegen 0.2.0 copy "remote_config_codegen: ^0.2.0" to clipboard
remote_config_codegen: ^0.2.0 copied to clipboard

Generate typed Dart Remote Config clients and JSON models from a JSON manifest.

Remote Config Codegen #

pub version CI

remote_config_codegen is a Dart CLI that generates a type-safe Firebase Remote Config access API and Dart JSON models from a JSON Manifest. It lets Flutter applications read Firebase Remote Config values through typed methods instead of string keys, Firebase getter selection, and manual JSON parsing.

What it generates #

Define Firebase Remote Config parameters and JSON value shapes once in a JSON Manifest:

{
  "parameters": {
    "example_param_1": {
      "valueType": "NUMBER",
      "defaultValue": 42
    },
    "example_param_2": {
      "valueType": "JSON",
      "defaultValue": {
        "items": [
          { "name": "coffee", "background_color": "#6750A4" }
        ]
      },
      "valueSchema": { "$ref": "#/$defs/MenuConfig" }
    }
  },
  "parameterGroups": {
    "example_group": {
      "parameters": {
        "example_param_3": {
          "valueType": "BOOLEAN",
          "defaultValue": true
        }
      }
    }
  },
  "$defs": {
    "MenuConfig": {
      "type": "object",
      "required": ["items"],
      "properties": {
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["name"],
            "properties": {
              "name": { "type": "string" },
              "background_color": { "type": "string" }
            }
          }
        }
      }
    }
  }
}

The CLI then generates a Firebase-backed, typed API. With the default json_serializable serializer, the relevant output is equivalent to:

// remote_config_models.dart
@JsonSerializable()
class MenuConfig {
  const MenuConfig({required this.items});

  factory MenuConfig.fromJson(Map<String, dynamic> json) =>
      _$MenuConfigFromJson(json);

  Map<String, dynamic> toJson() => _$MenuConfigToJson(this);

  final List<MenuConfigItemsItem> items;
}

@JsonSerializable()
class MenuConfigItemsItem {
  const MenuConfigItemsItem({required this.name, this.backgroundColor});

  factory MenuConfigItemsItem.fromJson(Map<String, dynamic> json) =>
      _$MenuConfigItemsItemFromJson(json);

  Map<String, dynamic> toJson() => _$MenuConfigItemsItemToJson(this);

  final String name;

  @JsonKey(name: 'background_color')
  final String? backgroundColor;
}

// remote_config_client.dart
class RemoteConfigClient {
  const RemoteConfigClient(this._remoteConfig);

  final FirebaseRemoteConfig _remoteConfig;

  int getExampleParam1Int() => _remoteConfig.getInt('example_param_1');

  double getExampleParam1Double() =>
      _remoteConfig.getDouble('example_param_1');

  MenuConfig getExampleParam2() {
    try {
      final decoded = jsonDecode(
        _remoteConfig.getString('example_param_2'),
      );
      if (decoded is! Map<String, dynamic>) {
        throw const FormatException('Expected a JSON object.');
      }
      return MenuConfig.fromJson(decoded);
    } on Object {
      return MenuConfig.fromJson(
        <String, dynamic>{
          'items': <dynamic>[
            <String, dynamic>{
              'name': 'coffee',
              'background_color': '#6750A4',
            },
          ],
        },
      );
    }
  }

  bool getExampleGroupExampleParam3() =>
      _remoteConfig.getBool('example_param_3');
}

Application code calls typed methods instead of using string keys, Firebase getter selection, or JSON parsing directly:

final client = RemoteConfigClient(FirebaseRemoteConfig.instance);
final int param1 = client.getExampleParam1Int();
final MenuConfig param2 = client.getExampleParam2();
final bool param3 = client.getExampleGroupExampleParam3();

Parameters under parameterGroups remain in the same generated client. Their method names use get<GroupName><ParameterName>, while Firebase lookups still use the original parameter key. Top-level parameters keep their existing get<ParameterName> methods. A manifest may contain either form or both.

Usage #

Place remote_config_codegen.yaml at the root of your Flutter project and run the CLI with the Manifest path.

dart run remote_config_codegen \
  --config config.json

Unless --settings is specified, the CLI reads remote_config_codegen.yaml from the current working directory.

Generation settings #

# remote_config_codegen.yaml
dart:
  output_directory: lib/src/generated/remote_config
  serializer: json_serializable
  remote_config_client_class_name: RemoteConfigClient

serializer supports json_serializable and freezed, and defaults to json_serializable when omitted. If remote_config_client_class_name is omitted, it defaults to RemoteConfigClient.

The generated code is Firebase-specific in the first release. The generated RemoteConfigClient receives FirebaseRemoteConfig directly through its constructor, so the consuming application needs firebase_remote_config.

Generated JSON models require these pinned packages in the consuming application:

dependencies:
  json_annotation: 4.12.0

dev_dependencies:
  build_runner: 2.15.1
  json_serializable: 6.14.0

To generate Freezed models, set serializer: freezed and use these pinned packages instead:

dependencies:
  freezed_annotation: 3.1.0
  json_annotation: 4.12.0

dev_dependencies:
  build_runner: 2.15.1
  freezed: 3.2.5
  json_serializable: 6.14.0

After running this CLI, generate the *.g.dart files from the consuming project:

dart run build_runner build

For the initial JSON Schema subset, properties that are not defined by the Schema are ignored by generated models. Remote Config value types are aligned with Firebase: STRING, BOOLEAN, NUMBER, and JSON. Within a JSON value schema, both optional properties and nullable properties are generated as nullable Dart fields (T?).

Every top-level NUMBER parameter generates get<Parameter>Int() and get<Parameter>Double(); grouped numbers include the group prefix in both names. If a JSON parameter cannot be parsed or converted into its model, the generated client falls back to the Manifest's defaultValue.

Every generated Dart file starts with // GENERATED CODE - DO NOT MODIFY BY HAND. Change the Manifest or JSON Schema and run the generator again instead of editing generated files.

Manifest example #

{
  "$schema": "./schema/remote_config_manifest.schema.json",
  "parameters": {
    "example_param_1": {
      "valueType": "NUMBER",
      "defaultValue": 42
    },
    "example_param_2": {
      "valueType": "JSON",
      "defaultValue": {
        "items": [
          { "name": "coffee", "background_color": "#6750A4" }
        ]
      },
      "valueSchema": { "$ref": "#/$defs/MenuConfig" }
    }
  },
  "parameterGroups": {
    "example_group": {
      "parameters": {
        "example_param_3": {
          "valueType": "BOOLEAN",
          "defaultValue": true
        }
      }
    }
  },
  "$defs": {
    "MenuConfig": {
      "type": "object",
      "required": ["items"],
      "properties": {
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["name"],
            "properties": {
              "name": { "type": "string" },
              "background_color": { "type": "string" }
            }
          }
        }
      }
    }
  }
}

The package provides the Meta Schema at schema/remote_config_manifest.schema.json. Consumer projects can refer to a copy of this file through $schema. A versioned URL will be provided when the package is published.

0
likes
150
points
152
downloads

Documentation

API reference

Publisher

verified publisherkeigomichi.com

Weekly Downloads

Generate typed Dart Remote Config clients and JSON models from a JSON manifest.

Repository (GitHub)
View/report issues
Contributing

License

MIT (license)

Dependencies

args, meta, yaml

More

Packages that depend on remote_config_codegen