---
description: Feature Driven Development with Bloc
---

# Understanding your project

### Approach



FDD is an iterative and incremental software development methodology that focuses on delivering features or functionalities in a systematic and organized manner. It divides the project into small, well-defined features, and each feature is developed independently.

Quickfire will structure your Flutter codebase around features. Each feature in your app corresponds to a set of related functionalities.

For each feature, quickfire will automatically create a corresponding Bloc (Business Logic Component). The Bloc is responsible for managing the business logic and state of that specific feature.

### Modularity :

Features are modular and independent. This modular structure makes it easier to understand, maintain, and scale the codebase. Developers can work on different features without interfering with each other's code.

### Readability and Maintainability :

The organization of code by features enhances code readability and maintainability. Developers can easily locate and work on specific parts of the application.

### Communication between features :

Features can communicate with each other through well-defined interfaces, events, or any other suitable mechanism (In Our Case We Are Using Bloc). This ensures a clean and controlled flow of information between different parts of the app.



## Understanding The Folder Architecture

```
lib/

  constants/
    dimensions.dart
    
  features/
  
    home/
      bloc/
        home_bloc.dart
        home_event.dart
        home_state.dart
      ui/
        home_screen.dart
      repo/
      widgets/
      
    admin/
      bloc/
        admin_bloc.dart
        admin_event.dart
        admin_state.dart
      ui/
        admin_screen.dart
      repo/
      widgets/
      
  shared/
     nav_bar.dart
     
 main.dart

```

### Constants Folder

```dart
import 'package:flutter/widgets.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

double getScreenWidth(BuildContext context) {
  return MediaQuery.of(context).size.width;
}

double getScreenheight(BuildContext context) {
  return MediaQuery.of(context).size.height;
}
```

In this file a [GlobalKey](https://api.flutter.dev/flutter/widgets/GlobalKey-class.html) is created, which has two methods `getScreenWidth` and `getScreenheight` which you can use in the entire application to get rid of&#x20;

```
MediaQuery.of(context).size.height;
```



### Features Folder

Inside `lib/features/` a folder is created for every feature.

Each feature contains 4 subfolders.&#x20;

* bloc folder ->  Contains Bloc files
* ui folder -> Contains a stateless scaffold
* repo folder -> You can use this folder to call your services
* widgets folder -> Common widgets for this feature

#### Bloc folder

* feature\_bloc.dart

```dart
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';

part 'home_event.dart';
part 'home_state.dart';

class HomeBloc extends Bloc<HomeEvent, HomeState> {
  HomeBloc() : super(HomeInitial()) {
    on<HomeEvent>((event, emit) {
      // TODO: implement event handler
    });
  }
}
```

* feature\_state.dart

```dart
part of 'home_bloc.dart';

@immutable
sealed class HomeState {}

final class HomeInitial extends HomeState {}
```

* feature\_event.dart

```dart
part of 'home_bloc.dart';

@immutable
sealed class HomeEvent {}
```

#### UI Folder

```dart
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('HomeScreen '),
      ),
    );
  }
}
```



### Understanding the Onboarding Feature

There are three basic scaffolds named as `intro_page1.dart` `intro_page2.dart` `intro_page3.dart`&#x20;

`on_boarding_screen.dart` controls all the three intro pages using `pageview`&#x20;

Quickfire relies on `shared_preferences` to show  the on\_boarding\_screen only one time.



### Understanding Navigation Screen

Quickfire creates a nav\_bar with all the UI files automatically for your app based on the features.

This NavigationScreen Widget acts as root of your UI.



### Setting Up Appwrite

Create a new project on appwrite and set it up for flutter.





Inside the `void main()` , add your project\_id and project\_endpoint

```dart
 Client client = Client();
  client = Client()
      .setEndpoint("<YOUR_PROJECT_ENDPOINT>")
      .setProject("<YOUR_PROJECT_ID>");
  Account account = Account(client);
```





Inside `lib/features/auth/service/auth_status.dart`&#x20;

```dart
String? get userid => _currentUser.id; // Replace this line with the bottom line

String? get userid => _currentUser.$id; // added dollar symbol before 'id'.
```

In the `init` function in `lib/features/auth/service/auth_status.dart`

```dart
  // Initialize the Appwrite client
  init() {
    client
        .setEndpoint('replace_with_your_endpoint')
        .setProject('replace_with_project_name')
        .setSelfSigned();
    account = Account(client);
  }
```





Inside `android/app/src/main/AndroidManifest.xml`



Replace your app name with the name of your project.

Add a `$` before `{applicationName}` like `${applicationName}` and remove the comment.

```
android:label="<YOUR-APP-NAME>"
android:name="{applicationName}" <-- add dollar sign before {applicationName} -->
```



That's it appwrite authentication has been setup on your project successfully :tada:



### Setting up Firebase

Create a new project on Firebase console.

Run `flutterfire configure` inside the project

[Generate SHA Keys](generate-sha) and add them to your firebase project settings.

Select your project.

### Setting up FCM

You just need a unique channel inside `AndroidManifest.xml`

```
android:value="<channel_name>"  <-- create a uniques channel name-->
```

Now go inside `lib/features/notification/notification_services.dart`&#x20;

Create a unique FCM Key from Google Cloud and add it here

```dart
'Authorization': 'key=<FIREBASE_CLOUD_MESSAGING_KEY>'

"android_channel_id": "<CHANNEL_NAME>" // replace it with your channel name

AndroidNotificationDetails(
'<channel_name>', // Change this to a unique channel ID
'Your Channel Name', // no need to change this
channelDescription: '',
importance: Importance.max,
priority: Priority.high,
);

```

