import 'dart:convert' show json ; json . decode ( someString ) ; json . encode ( encodableObject ) ;

json.decode returns a dynamic type, which is probably not very useful

You should describe each entity as a Dart class with fromJson and toJson methods

class User { String displayName ; String photoUrl ; User ( { this . displayName , this . photoUrl } ) ; User . fromJson ( Map < String , dynamic > json ) : displayName = json [ 'displayName' ] , photoUrl = json [ 'photoUrl' ] ; Map < String , dynamic > toJson ( ) { return { 'displayName' : displayName , 'photoUrl' : photoUrl , } ; } } final user = User . fromJson ( json . decode ( jsonString ) ) ; json . encode ( user . toJson ( ) ) ;

However this approach is error-prone (e.g. you can forget to update map key after class field was renamed), so you can use json_serializable as an alternative

Add json_annotation , build_runner and json_serializable to dependencies

dependencies : json_annotation : ^2.0.0 dev_dependencies : build_runner : ^1.0.0 json_serializable : ^2.0.0

Update your code

import 'package:json_annotation/json_annotation.dart' ; part 'user.g.dart' ; @JsonSerializable ( ) class User { String displayName ; String photoUrl ; User ( { this . displayName this . photoUrl } ) ; factory User . fromJson ( Map < String , dynamic > json ) { return _$ UserFromJson ( json ) ; } Map < String , dynamic > toJson ( ) = > _$ UserToJson ( this ) ; } final user = User . fromJson ( json . decode ( jsonString ) ) ; json . encode ( user ) ;

Run flutter packages pub run build_runner build to generate serialization/deserialization code

To watch for changes run flutter packages pub run build_runner watch

Read more about json and serialization here