2
Interface
I wanted to use interface in Dart, but after a lot of searching, discover that there is not, so I did it this way, I created an abstract class:
abstract class IModel {
  String _uid;
  Map<String, dynamic> toJson();
  IModel.fromJson(Map<String, dynamic> json);
  String get uid => _uid;
  set uid(String value) {
    _uid = value;
  }
}
And I implemented it this way:
import 'package:whatsapp/services/model/imodel.dart';
class UserModel implements IModel {
  @override
  String uid;
  String _name;
  String _email;
  @override
  Map<String, dynamic> toJson() => {"name": _name, "email": _email};
  @override
  UserModel.fromJson(Map<String, dynamic> json) {
    uid = json["uid"];
    _name = json["name"];
    _email = json["email"];
  }
  String get email => _email;
  set email(String value) {
    _email = value;
  }
  String get name => _name;
  set name(String value) {
    _name = value;
  }
}
Generic
So I created the following class to manage Firebase:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:whatsapp/services/model/imodel.dart';
import '../firestore_service.dart';
class BaseService<T extends IModel> extends FirestoreService {
  BaseService(String path) : super(path);
  @override
  Future<List<T>> GetAll() async {
    List<DocumentSnapshot> documentSnapshotList = await GetAllDocuments();
    documentSnapshotList.map((item) => _fromJson(item));
  }
  Future<T> GetById(String id) async {
    return _fromJson(await GetDocumentById(id));
  }
  Future<String> Create(T model) async =>
      (await CreateDocument(model.toJson())).documentID;
  Future<String> CreateOrUpdate(T model) => model.uid == null
      ? Create(model)
      : CreateOrUpdateDocument(model.uid, model.toJson());
  Future<void> Delete(String id) => DeleteDocument(id);
  T _fromJson(DocumentSnapshot snapshot) {
    var newItem = snapshot.data;
    newItem["uid"] = snapshot.documentID;
    return T.fromJson(newItem);
  }
}
At first I wanted to use an interface to solve this problem, instead of "T" I would use the interface, so decide to use Generic, everything worked fine until I need to instantiate "T":
return T.fromJson(newItem);
I have the following mistake:
Compiler message:
lib/services/model/base_service.dart:31:14: Error: The method 'fromJson' isn't defined for the class 'Type'.
 - 'Type' is from 'dart:core'.
Try correcting the name to the name of an existing method, or defining a method named 'fromJson'.
    return T.fromJson(newItem);
             ^^^^^^^^
Summary
I searched and did not find any way to instantiate a Generic or create an interface, my idea is to create a base class to manage Firebase and only pass the class that will be persisted.
Note: The funny thing is that I inform that my "T" is an "Imodel":
BaseService<T extends IModel>And yet he doesn’t recognize "fromJson" from "Imodel".
Flutter does not have Reflection, it seems that even the to implement, but it does not get very cool.
– Matheus Ribeiro
I even tried, but it didn’t work.
– Wictor Chaves