parse static method
Implementation
static GoogleServicesConfig parse(String text, {String source = '<memory>'}) {
final Object? decoded = json.decode(text);
if (decoded is! Map<String, Object?>) {
throw FormatException('$source: expected a JSON object');
}
Map<String, Object?> obj(Map<String, Object?> from, String key) {
final v = from[key];
if (v is! Map<String, Object?>) {
throw FormatException('$source: missing object "$key"');
}
return v;
}
String str(Map<String, Object?> from, String key) {
final v = from[key];
if (v is! String || v.isEmpty) {
throw FormatException('$source: missing string "$key"');
}
return v;
}
final info = obj(decoded, 'project_info');
// One project can register several apps. Without a package name to match,
// a single client is unambiguous; more than one is not, so say so instead
// of silently taking the first.
final clients = decoded['client'];
if (clients is! List || clients.isEmpty) {
throw FormatException('$source: no "client" entries');
}
if (clients.length > 1) {
throw FormatException(
'$source: ${clients.length} clients registered; this loader needs '
'exactly one to pick without ambiguity',
);
}
final client = clients.first;
if (client is! Map<String, Object?>) {
throw FormatException('$source: malformed "client" entry');
}
final keys = client['api_key'];
if (keys is! List || keys.isEmpty || keys.first is! Map<String, Object?>) {
throw FormatException('$source: no "api_key" for the client');
}
return GoogleServicesConfig(
appId: str(obj(client, 'client_info'), 'mobilesdk_app_id'),
apiKey: str(keys.first as Map<String, Object?>, 'current_key'),
projectId: str(info, 'project_id'),
// Absent for a project with no Realtime Database, which is most of
// them. Failing here would stop an app that never asks for one.
databaseUrl: switch (info['firebase_url']) {
final String v when v.isNotEmpty => v,
_ => null,
},
storageBucket: info['storage_bucket'] as String?,
messagingSenderId: info['project_number'] as String?,
);
}