remote_config_codegen 0.2.0
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 #
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.