Instagram Clone Clean Architecture – Part 6

Table of Contents

Entity - Instagram clone part 6

authentication - Instagram clone part 6

In the first 5 Parts of this series, you learned some core concepts of Clean Architecture and with this we’ve created bunch of folders in our project and we also build the beautiful UI of our Instagram application. And we also added some packages in our project’s .yaml file that we will use throughout this project.

Now in (Instagram Clone Clean Architecture – Part 6)  we will take start from the Domain Layer which is inner most and independent layer and it’s not going to hold any sort of concrete implementation but there will goes our core contracts or abstract classes and later these will be implemented in Data Layer.

The entity business object, what kind of data will going to store in our Cloud Firestore Database? First we’re going to have a User then we will authenticate that user in our application but … what kind of data our user / user entity going to hold? Well, the basic data of user is like user name, email, password etc. But in our case if you look the Profile Page or Edit Profile Page below create a directory in your domain > entities > and name it to user and inside this create a dart file user_entity.dart.


					import 'package:equatable/equatable.dart';

class UserEntity extends Equatable {
  final String? uid;
  final String? username;
  final String? name;
  final String? bio;
  final String? website;
  final String? email;
  final String? profileUrl;
  final List? followers;
  final List? following;
  final num? totalFollowers;
  final num? totalFollowing;

  // will not going to store in DB
  final String? password;
  final String? otherUid;


  List<Object?> get props => [

We’ve extended our UserEntity class with Equatable that’s a package for value equality you can checkout it’s documentation.

Use Cases - Instagram clone part 6

These Use Cases are the places where our business logic will get executed, as I said in case of the Cubit (State Management Solution) subset of Bloc this will not going to hold so much logic but this will delegate its work to Use Cases and here the Use Cases will get the data from the Repository (Contract) class.

Repository - Instagram clone part 6


What are you expecting? Like how our contract would look like? As in this part we’re only writing code for User so we’re going to have all of the methods of User for now and later there will be more methods also for other logic like Post, Comment etc, create a dart file in your domain > Repository and name it to firebase_repository.dart.

					import 'package:instagram_clone_app/features/domain/entities/user/user_entity.dart';

abstract class FirebaseRepository {
  // Credential
  Future<void> signInUser(UserEntity user);
  Future<void> signUpUser(UserEntity user);
  Future<bool> isSignIn();
  Future<void> signOut();

  // User
  Stream<List<UserEntity>> getUsers(UserEntity user);
  Stream<List<UserEntity>> getSingleUser(String uid);
  Future<String> getCurrentUid();
  Future<void> createUser(UserEntity user);
  Future<void> updateUser(UserEntity user);

Now you might be thinking how our Use Cases would be? First Go to > domain > usecases > and there create a directory user because there will go all the Use Cases of user and then start creating the .dart files according to the methods in our Repository (contract) class for each method there will be separate Use Case like:


					class SignInUserUseCase {
  final FirebaseRepository repository;

  SignInUserUseCase({required this.repository});

  Future<void> call(UserEntity userEntity) {
    return repository.signInUser(userEntity);

We’ve a separate class we get the Instance of FirebaseRepository as repository then create a call() method It’s return type will be according to the return type the particular method have like in Repository (contract) class like the return type of signInUser is Future<void> so here the return type of method is same and also the parameters will be accordingly If it accepts String uid so pass the String uid as a parameter or if it accepts UserEntity pass it according to this or if it’s not accepting any so keep it empty.

One more example of usecase:


					class GetCurrentUidUseCase {
  final FirebaseRepository repository;

  GetCurrentUidUseCase({required this.repository});

  Future<String> call() {
    return repository.getCurrentUid();

So at last our Domain files Structure look like this:


We’re done with our User Part of Domain Layer in the next article we will go for the Data Layer where we will implement that contract class which is in the Domain Layer and also the methods we’ve created in our Repository (contract) class and also the User Model, in order to not miss the upcoming great video where you’ll learn how we can do real implementation with Clean Architecture be sure you subscribe to the channel and hit the bell icon to make sure you get notified whenever new video is uploaded.

Have any Questions? Find me on

Leave a Reply